前端解决跨域问题的常用方法

2019-11-6    seo达人

首先,跨域是什么?



只要协议、域名、端口有任何一个不同,都被当作是不同的域。为什么三者任何一个不同就会产生跨域呢,想想也很容易知道,要是很随便引用什么外部文件,不同标签下的页面引用类似的彼此的文件,浏览器很容易懵逼的,保障不了安全问题,但在安全限制的同时也给注入iframe或是ajax请求上带来了不少麻烦。所以我们要通过一些方法使本域的js能够操作其他域的页面对象或者使其他域的js能操作本域的页面对象



但有两点至少要清楚:



如果是协议和端口造成的跨域问题“前台”是无能为力的;

在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。

(“URL的首部”指window.location.protocol +window.location.host,也可以理解为“Domains, protocols and ports must match”。)

1.通过HTML5的postMessage方法跨域



页面M通过postMessage方法发送消息如下:



window.onload = function() {  

    var iframe_dom = document.getElementById('iframId');  

    var targetOrigin = "http://www.baidu.com";  

    iframe_dom.contentWindow.postMessage('hello world!', targetOrigin);  

};

备注:



postMessage的使用方法:



originwindow.postMessage(message, targetOrigin);



originwindow:是说的目标窗口,即要给某个window发消息,是 window.frames 属性的成员或者由 window.open 方法创建的窗口

message: 是要发送的消息,类型为 String、Object (但IE8、9 不支持)

targetOrigin: 是限定消息接收范围,不限制请使用 '*

页面N通过message事件监听并接受消息如下:



let onmessage = function (event) {  

  var data = event.data;//由发送窗口传过来的消息内容  

  var origin = event.origin;//由发送窗口传过来的消息来源地址  

  var source = event.source;//源Window对象  

  if(origin=="http://www.baidu.com"){  

    console.log(data);//hello world!  

  }  

};  

if (typeof window.addEventListener != 'undefined') {  

  window.addEventListener('message', onmessage, false);  

} else if (typeof window.attachEvent != 'undefined') {  

  //for ie  

  window.attachEvent('onmessage', onmessage);  

}

或者为了防止接入方的命名冲突,也可以约定事件名,以此加以区分



例如



window.addEventListener("message", function(event) {

  if (

    event &&

    typeof event.data == "object" &&

    event.data.event == "FUNCTION_NAME"

){

document.getElementById("val").innerHTML = event.data.value;

} });

2.通过JSONP



上面那种方式的通信是双向的,页面与iframe或是页面与页面之间的



JSONP主要是封装好的请求方式添加callback,这个callback是由前后端约定好的



它的优劣势:



JSONP的优点:它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制;它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持;并且在请求完毕后可以通过调用callback的方式回传结果。

JSONP的缺点:它只支持GET请求而不支持POST等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题;无法判断它是否请求成功,只能通过timeout

3.CORS跨域



实现CORS通信的关键是服务器端,只要服务端那边实现了CORS接口,就可以跨源通信



CORS(Cross-Origin Resource Sharing)跨域资源共享,定义了必须在访问跨域资源时,浏览器与服务器应该如何沟通。CORS背后的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是失败。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉



服务器端对于CORS的支持,主要就是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,便可以允许Ajax进行跨域的访问



 



CORS和JSONP对比



JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。



使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。



JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS)。



CORS与JSONP相比,显然更为先进、方便和可靠。



4.设置代理



目前市场上用vue技术不在少数,下面介绍一种配置代理方式



在vue.config.js该文件里面配置如下:



 devServer: {

        port: 8001,

        open: true,

        disableHostCheck: true,

        proxy: {

            '/api': {

                target: 'https:/xxx.com',

                secure: true, // false为http访问,true为https访问

                ws: true,

                changeOrigin: true,

                pathRewrite: {

                    '^/api': ''

                }

             }

        }

 }

 



后面请求是需要带上‘/api’请求即可


分享本文至:

日历

链接

blogger

蓝蓝 http://www.lanlanwork.com

存档