老生常谈——图解3种跨域解决方案

没有纯前端的跨域解决方案,遇到跨域,请找后端协商方案!

什么是跨域?

同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。 ——MDN

跨域的产生来源于浏览器的同源策略。当你访问(请求)的资源和当前页的协议、域名、端口中有一个不同时,就会遇到跨域问题。

常见的解决方案有以下 3 种。

1. jsonp

jsonpXMLHttpRequest 完全没有关系。

html 中的某些标签具有访问跨域资源的特性。例如,我们通过使用 script 标签向其他服务器请求数据,这种技术我们称为 jsonp。

具体行为:创建一个 script 标签,给 src 赋值请求的 url,并添加到 document 中去,然后浏览器就会发送一个 GETHTTP 请求以下载 src 属性所指向的 URL

示意图:

具体代码就不贴了,如果请求超时了,会触发 script 标签的 onerror 事件,类似

1
2
3
4
5
a = new Image();
a.src = "http://www.baidu.com";
a.onerror = function(){
console.log('load failed')
}

图片资源请求失败会触发它的 onerror事件。

2. cors 跨域资源共享

这是后端来处理的,前端不需要了解太多。主要是通过设置 responseHeaderAccess-Control-Allow-Origin 字段

这里可以参考 “跨域资源共享 CORS 详解——阮一峰” 。 里面讲的蛮好的, 包括什么是简单请求,什么是非简单请求,什么情况下,浏览器会先尝试发起 options 请求。

示意图:

CORS

3. 代理

我这里说的代理是指 中间层代理 和 nginx 反向代理。

在我的理解里, 这两个东西其实差不多,因为是服务端来处理,而服务端是没有跨域问题的。

举个例子,我用一个 node 服务来做中间转发层。我在 www.ccc.com/a.html 中向同源的 www.ccc.com/api/v1/getUserAge?id=106 发起请求,node 服务接收到这个请求后,在 node 服务端向另外一个服务器比如 www.aaa.com/api/v1/getUserAge?id=106 发起请求,等它返回结果后,再将请求结果返回给 www.ccc.com/a.html

示意图:

node转发

nginx 我没怎么用过,但应该也差不多,有个对外和对内的请求的拦截器之类的东西,在里面设置转发。

就写到这里,如果有那里理解的不对,还请指正,谢谢 🙏 : )