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

首先,跨域是什么?

只要协议、域名、端口有任何一个不同,都被当作是不同的域。为什么三者任何一个不同就会产生跨域呢,想想也很容易知道,要是很随便引用什么外部文件,不同标签下的页面引用类似的彼此的文件,浏览器很容易懵逼的,保障不了安全问题,但在安全限制的同时也给注入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’请求即可

 

  • 9
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值