美文网首页饥人谷技术博客
对跨域的解决方式

对跨域的解决方式

作者: cce117b0a0ce | 来源:发表于2017-08-06 16:54 被阅读52次

浏览器安全的基石是"同源政策"。所谓"同源"指的是"三个相同"。

  • 协议相同
  • 域名相同
  • 端口相同

同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。虽然这些限制是必要的,但是有时很不方便,合理的用途也受到影响。所以引出跨域的几种解决方式。如有错误请指正。

首先对于ajax的请求不能发送:

  • JSONP
  • CROS
  1. JSONP

JSONP是服务器与客户端跨源通信的常用方法。最大特点就是简单适用,老式浏览器全部支持,服务器改造非常小。
它的基本思想是,网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。

$('.change').addEventListener('click', function(){
    var script = document.createElement('script');
    script.src = 'http://127.0.0.1:8080/getNews?callback=appendHtml';
    //向服务器http://127.0.0.1:8080发送请求,请求的查询字符串有一个callback参数,用来指定回调函数的名字
    document.head.appendChild(script);
    //服务器收到请求后,将数据放在回调函数的参数位置返回
    document.head.removeChild(script);
  })
  function appendHtml(news){
    var html = '';
    for( var i=0; i<news.length; i++){
      html += '<li>' + news[i] + '</li>';
    }
    console.log(html);
    $('.news').innerHTML = html;
  }
  function $(id){
    return document.querySelector(id);
  }

上面代码通过动态添加<script>元素,向服务器http://127.0.0.1:8080发出请求。注意,该请求的查询字符串有一个callback参数,用来指定回调函数的名字,这对于JSONP是必需的。

由于<script>元素请求的脚本,直接作为代码运行。这时,只要浏览器定义了appendHtml函数,该函数就会立即调用。作为参数的JSON数据被视为JavaScript对象,而不是字符串,因此避免了使用JSON.parse的步骤。

服务器收到请求后,将数据传给回调函数返回

app.get('/getNews', function(req, res){

    var news = [
        "第11日前瞻:中国冲击4金 博尔特再战200米羽球",
        "正直播柴飚/洪炜出战 男双力争会师决赛",
        "女排将死磕巴西!郎平安排男陪练模仿对方核心",
        "没有中国选手和巨星的110米栏 我们还看吗?",
        "中英上演奥运金牌大战",
        "博彩赔率挺中国夺回第二纽约时报:中国因对手服禁药而丢失的奖牌最多",
        "最“出柜”奥运?同性之爱闪耀里约",
        "下跪拜谢与洪荒之力一样 都是真情流露"
    ]
    var data = [];
    for(var i=0; i<3; i++){
        var index = parseInt(Math.random()*news.length);
        data.push(news[index]);
        news.splice(index, 1);
    }


    var cb = req.query.callback;
    if(cb){
        res.send(cb + '('+ JSON.stringify(data) + ')');
    }else{
        res.send(data);
    }
})
  1. CORS

CORS是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是W3C标准,是跨源AJAX请求的根本解决方法。相比JSONP只能发GET请求,CORS允许任何类型的请求。CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。
只要同时满足以下两大条件,就属于简单请求。

(1) 请求方法是以下三种方法之一:
- HEAD
- GET
- POST
(2)HTTP的头信息不超出以下几种字段:
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

凡是不同时满足上面两个条件,就属于非简单请求。
浏览器对这两种请求的处理,是不一样的。

  • 简单请求
    var xhr = new XMLHttpRequest();
    xhr.open('get', 'http://b.hth:8080/getNews', true);
    xhr.send();
    //xhr.open的传的url为绝对路径,也就是你要跨域访问的接口地址

服务器端:

res.header("Access-Control-Allow-Origin", "http://a.hth:8080"); 
//指定可以请求数据的域名为http://a.hth:8080
  • 非简单请求

非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUTDELETE,或者Content-Type字段的类型是application/json

非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。

浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

var url = 'http://api.alice.com/cors';
var xhr = new XMLHttpRequest();
xhr.open('PUT', url, true);
xhr.setRequestHeader('X-Custom-Header', 'value');
xhr.send();

上面代码中,HTTP请求的方法是PUT,并且发送一个自定义头信息X-Custom-Header

下面设置请求回应设置http的头部Access-Control-Allow-Origin*,表示同意任意跨源请求。

res.header("Access-Control-Allow-Origin", "*"); 

iframe

如果两个网页不同源,就无法拿到对方的DOM。典型的例子是iframe窗口和window.open方法打开的窗口,它们与父窗口无法通信。

  • 降域:
    如果两个窗口一级域名相同,只是二级域名不同,那么设置上一节介绍的document.domain属性,就可以规避同源政策,拿到DOM。
  • window.postMessage
    HTML5为了解决这个问题,引入了一个全新的API:跨文档通信 API
window.frames[0].postMessage(this.value,'*');//发送消息
window.parent.postMessage(this.value, '*');

参考链接:

相关文章

  • springboot 在整合shiro后,跨域就失效了。

    原springboot 解决跨域问题 使用 tomcat 中的 Filter的方式解决跨域

  • 跨域

    ??JSONP只能解决GET请求跨域,不能解决POST请求跨域问题,XHR2可以解决GET,POST方式的请求跨域...

  • 对跨域的解决方式

    浏览器安全的基石是"同源政策"。所谓"同源"指的是"三个相同"。 协议相同 域名相同 端口相同 同源政策的目的,是...

  • AJAX

    题目 手写一个ajax 跨域的常用实现方式 知识点 XMLHttpRequest 状态码 跨域:同源策略,跨域解决...

  • Vue实现跨域请求

    一般解决跨域问题可以通过CORS跨域、JSONP和反向代理跨域。下面分别介绍这三种跨域方式: 1、CORS 以ne...

  • SpringBoot 实现前后端分离的跨域访问(CORS)

    springBoot小白写博客时遇到了跨域问题,顺便记录一下踩过的坑 springboot解决跨域的几种方式 方式...

  • Flask-cors跨域

    什么是跨域 为什么要考虑跨域问题 同源策略 解决跨域问题 方式一: 使用 JSONP (一种非Ajax技术,需要前...

  • 跨域解决方式

    出于安全方面的考虑,浏览器遵从同源策略的原则。即同协议(http/https)、同域名(jianshu.com/j...

  • 跨域解决方式

    JSONP实现跨域 原理:网页通过添加一个 元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请...

  • 跨域 & 跨域的几种解决方式

    什么是跨域 跨域是由于浏览器同源策略的限制,它是对 JavaScript 的限制。浏览器不允许执行其他网站的脚本 ...

网友评论

    本文标题:对跨域的解决方式

    本文链接:https://www.haomeiwen.com/subject/jtfwlxtx.html