跨域问题,到底是怎么个事?
在你浏览网页的过程中,你的浏览器其实在不停地向各种服务器发送请求,获取数据,然后渲染出你看到的网页。
为了保护你的数据和隐私,浏览器有一种机制,叫做"同源策略"。
简单来说,同源策略就是浏览器规定,只有来自同一个"源"(协议,域名,端口都相同)的请求才能进行某些操作,比如读取 DOM,发送 AJAX 请求等。
但是现实中,我们经常需要从一个网站去获取另一个网站的数据,这就需要绕过或者说"解决"同源策略限制,这就涉及到了"跨域"的问题。
解决跨域,一般有三个方法:
- JSONP
- CORS
- 服务器反向代理
JSONP
我们先回到上世纪90年代,那个时候还没有XMLHttpRequest、AJAX这些现代浏览器提供的API。
那个时候的网页要获取远程数据,一种方式就是使用<script>
标签加载一个JavaScript文件。
由于<script>
标签的src属性并不受同源策略的约束,这就提供了一种可能性:我们可以在<script>
标签中向其他源请求数据。
具体如何操作呢?假设我们现在在a.com的页面上,我们想获取b.com的一些数据,那我们就可以在a.com上写下这样的代码:
<script>
function callback(data) {
console.log(data);
}
</script>
<script src="http://b.com/data.js"></script>
然后在b.com的服务器上,我们把data.js设置成这样:
callback({"name": "Tom", "age": 18});
这样,当a.com的页面加载的时候,就会执行callback
函数,传入我们在b.com定义的数据。这就是最初的JSONP。
但是现在我们已经有了更好的方法,如CORS,所以JSONP已经很少使用了。
CORS(跨源资源共享)
现在大部分现代浏览器都支持CORS。
CORS其实就是服务器告诉浏览器,它的资源可以被哪些源访问。具体是通过设置HTTP响应头来实现的。
比如,b.com的服务器可以在响应头中加入这样一行:
Access-Control-Allow-Origin: http://a.com
这就告诉浏览器,a.com可以访问b.com的资源。
那么在a.com上,我们就可以使用XMLHttpRequest或者Fetch API等方式来请求b.com的数据了,浏览器不会因为同源策略阻止我们的请求。
服务器代理
服务器代理其实就是我们创建一个服务器作为中间人,帮助我们获取其他源的数据。
比如,我们现在在a.com的页面上,我们想获取b.com的数据,由于同源策略,直接请求是不行的。
那么我们就可以在a.com的服务器上创建一个接口,比如/proxy
。
然后在a.com的页面上,我们请求/proxy
接口,然后由a.com的服务器去请求b.com的数据,然后再把数据返回给页面。
- 在源A的前端代码中,我们不再直接请求源B,而是请求我们刚才在服务器上设置的
/proxy
接口。 - 当
/proxy
接口接收到请求后,服务器会转而去请求源B的数据。因为服务器并不受同源策略的限制,所以这个请求不会被阻止。 - 服务器获取到源B的数据后,再把这些数据通过
/proxy
接口返回给前端。前端就成功地获取到了源B的数据。
最后我们总结一下:
- 数据安全:解决跨域问题时,一定要注意数据安全。不要随意设置
Access-Control-Allow-Origin
为*
,这将允许任何源访问你的服务器资源,可能会带来安全风险。 - 性能问题:使用服务器代理时,需要注意可能会对服务器性能产生影响。因为所有的请求都会经过你的服务器,可能会增加服务器的负担。
- 前后端分离开发:在前后端分离的开发模式中,开发环境常常会遇到跨域问题。常见的解决方式是在开发服务器上设置代理,将前端的请求转发到后端服务器。
转载自:https://juejin.cn/post/7244487194174472247