老生常谈——图解3种跨域解决方案
没有纯前端的跨域解决方案,遇到跨域,请找后端协商方案!
什么是跨域?
同源策略限制从一个源加载的文档或脚本如何与来自另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的关键的安全机制。 ——MDN
跨域的产生来源于浏览器的同源策略。当你访问(请求)的资源和当前页的协议、域名、端口中有一个不同时,就会遇到跨域问题。
常见的解决方案有以下3种。
1. jsonp
jsonp 和 XMLHttpRequest 完全没有关系。
html中的某些标签具有访问跨域资源的特性。例如,我们通过使用 script
标签向其他服务器请求数据,这种技术我们称为jsonp。
具体行为:创建一个 script
标签,给 src
赋值请求的url,并添加到 document
中去,然后浏览器就会发送一个 GET
的 HTTP 请求以下载 src
属性所指向的 URL 。
示意图:
具体代码就不贴了,如果请求超时了,会触发 script
标签的 onerror
事件,类似
a = new Image();
a.src = "http://www.baidu.com";
a.onerror = function(){
console.log('load failed')
}
图片资源请求失败会触发它的 onerror
事件。
2. cors 跨域资源共享
这是后端来处理的,前端不需要了解太多。主要是通过设置 responseHeader
的 Access-Control-Allow-Origin
字段
这里可以参考 "跨域资源共享 CORS 详解——阮一峰" 。 里面讲的蛮好的, 包括什么是简单请求,什么是非简单请求,什么情况下,浏览器会先尝试发起 options
请求。
示意图:
CORS3. 代理
我这里说的代理是指 中间层代理 和 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 我没怎么用过,但应该也差不多,有个对外和对内的请求的拦截器之类的东西,在里面设置转发。
就写到这里,如果有那里理解的不对,还请指正,谢谢🙏 : )