跨域解决方案

作者: FWHeart | 来源:发表于2017-10-04 17:45 被阅读0次

跨域解决方案

跨域解决方案有:设置document.domain,使用带src标签,JSONP,navigation对象,CORS,window.postMessage,片段标识符,window.name,WebSocket

设置document.domain

  • 原理:相同主域名不同子域名下的页面,可以设置document.domain让它们同域
  • 限制:同域document提供的是页面间的互操作,需要载入iframe页面
// URL http://a.com/foo
var ifr = document.createElement('iframe');
ifr.src = 'http://b.a.com/bar'; 
ifr.onload = function(){
    var ifrdoc = ifr.contentDocument || ifr.contentWindow.document;
    ifrdoc.getElementsById("foo").innerHTML);
};

ifr.style.display = 'none';
document.body.appendChild(ifr);

需要设置iframe的domain,将 document.domain往上设置一级,这样即可操作DOM和Cookie

document.domain = 'a.com'

使用带src标签

  • 原理:所有具有src属性的HTML标签都是可以跨域的,包括<img>, <script>,<iframe>
  • 限制:只能用于GET方法

JSONP

利用script标签可以跨域这点,跨域获得的脚本包含一个客户端和服务器端约定好的回调函数,以及服务器端发送的数据。

jQuery实现

//URL具有callback参数时, jQuery将会把它解释为一个JSONP请求,创建一个<script>标签来完成该请求。
$.getJSON( "http://b.a.com/bar?callback=callback", function( data ){
    // 处理跨域请求得到的数据
});

JS实现

function loadJsonp(url,callback){
    var script = document.createElement('script'),
    rand = Math.random().toString().substring(2, 8),
    functionName = "getJsonStr" + rand;

    script.src = url + "?callback=" + functionName;

    window[functionName] = function(data) {
        if (callback) {
            callback(data);
        }
        try {
            delete window[functionName];
        } catch (e) {
            window[functionName] = undefined;
        }
    };

    var head = document.getElementsByTagName('head')[0];
    script.onload = function() {
        script.onload = undefined;
        head.removeChild(script);
    };
    script.onerror = function(e) {
        console.error(e);
    };

    head.appendChild(script);
}

跨域资源共享(CORS)

  • 原理:服务器设置Access-Control-Allow-OriginHTTP响应头之后,浏览器将会允许跨域请求,H5推荐的跨域方式。
  • 限制:浏览器需要支持HTML5,可以支持POST,PUT等方法

跨域发送Cookie

将xhr的属性withCredentials设置为true后,即可携带目标域的Cookie

// 原生
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.withCredentials = true;
xhr.send();
// jQ
$.ajax({
   url: a_cross_domain_url,
   xhrFields: {
      withCredentials: true
   }
});

还需要服务器端设置Access-Control-Allow-Credentials响应头为true,并且将Access-Control-Allow-Origin设置为请求对应的域名

既然Access-Control-Allow-Origin只允许单一域名, 服务器可能需要维护一个接受 Cookie 的 Origin 列表, 验证 Origin 请求头字段后直接将其设置为Access-Control-Allow-Origin的值。 (这一实践来自 Stackoverflow) 值得注意的是在 CORS 请求被重定向后 Origin 头字段会被置为 null。 此时可以选择从Referer头字段计算得到Origin。

preflight

对于非简单请求,CORS 机制跨域会首先进行 preflight(一个 OPTIONS 请求), 该请求成功后才会发送真正的请求。 这一设计旨在确保服务器对 CORS 标准知情,以保护不支持 CORS 的旧服务器。

preflight.png

window.postMessage

  • 原理:HTML5允许窗口之间发送消息
  • 限制:浏览器需要支持HTML5,获取窗口句柄后才能相互通信

这是一个安全的跨域通信方法,postMessage(message,targetOrigin)也是HTML5引入的特性。 可以给任何一个window发送消息,不论是否同源。第二个参数可以是*但如果你设置了一个URL但不相符,那么该事件不会被分发。

// 页面A,URL: http://a.com/foo
var win = window.open('http://b.com/bar');
win.postMessage('Hello, bar!', 'http://b.com'); 
// 页面B,URL: http://b.com/bar
window.addEventListener('message',function(event) {
    console.log(event.data);
});

片段标识符

  • 原理:改变网页#后面的部分,被改变的网页可以通过监听onhashchange事件得到通知
  • 限制:URL具有长度的限制,只能传送字符串
// A窗口
var src = originURL + '#' + data;
document.getElementById('myIFrame').src = src;
// B窗口
window.onhashchange = function(){
    var message = window.location.hash;
}

window.name

  • 原理:只要在同一个窗口里,前一个网页设置了这个属性,后一个网页可以读取它。
  • 限制:必须监听子窗口window.name属性的变化,影响网页性能。

WebSocket

  • 原理:WebSocket使用ws、wss作为通信协议,改协议没有同源策略
  • 限制:需要浏览器支持

参考文献

JS高程(第三版)
Web开发中跨域的几种解决方案
浏览器同源策略及其规避方法
CORS 跨域发送 Cookie
CORS 跨域中的 preflight 请求

相关文章

  • Web前后端跨域问题处理

    跨域问题有前台跨域(iframe间)和后台跨域。 前台跨域的解决方案可以采用跨域文档通讯(Cross domain...

  • 跨域问题,解决方案

    跨域问题,解决方案 - Nginx反向代理跨域问题,解决方案 - CORS方案此为原作者的链接:跨域问题,解决之道

  • 前端如何解决常见跨域问题

    跨域解决方案 1、 通过jsonp跨域 2、 document.domain + iframe跨域 3、 loca...

  • 开发环境跨域和生产环境跨域

    开发环境跨域 前后端分离,IP地址不同,请求数据必然导致跨域问题;解决方案:proxy设置 生产环境跨域 解决方案...

  • 浏览器跨域及其解决方案

    title: 浏览器跨域及其解决方案author: Maydate: 20220428 什么是跨域跨域的表现解决跨...

  • 跨域解决方案

    跨域解决方案 跨域解决方案有:设置document.domain,使用带src标签,JSONP,navigatio...

  • 跨域

    参考资料 HTTP访问控制(CORS)跨域解决方案跨域详解

  • Angular访问WebApi出现options方法

    解决方案: 解决跨域:

  • 跨域解决方案(史上最易懂)

    跨域总结 1.跨域思路 跨域解决方案一般分为两种:前端解决,后端解决 1.1 前端解决方案 通过前端解决的思想就是...

  • ZUUL跨域问题

    云环境中每个服务自己有跨域解决方案,而网关需要做最外层的跨域解决方案.如果服务已有跨域配置网关也有,会出现*多次配...

网友评论

    本文标题:跨域解决方案

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