基于 CORS 实现跨域请求的原理

目录

1、同源策略

2、CORS 是啥

3、CORS 的原理

4、CORS 的优缺点


1、同源策略

源:在任何网站的控制台输入:window.origin location.origin 可以得到当前源。源 = 协议+域名+端口号。

在说跨域之前,不得不先说一下浏览器的 同源策略同源策略是浏览器的一个安全功能,同源是指两个网址的 协议、域名、端口号 都相同,三者中只要有一个不同就是不同源。受同源策略的影响,运行在不同源的客户端脚本在没有明确授权的情况下,不能读写对方的资源,比如 abc.com 下的 JavaScript 脚本采用 Ajax 读取 xyz.com 里面的文档数据是会被拒绝的。这种浏览器的同源策略本意是防御非法攻击的,但是在前端开发中由于同源策略的存在,使得 Ajax 请求跨域数据时失败。针对这一问题衍生出了很多种解决跨域问题的方式,其中具有代表性的有 JSONP 和 CORS。

简而言之,同源策略:不同源的页面之间,不准互相访问数据。

上面的举例:abc.com 下的 JavaScript 脚本采用 Ajax 读取 xyz.com 里面的文档数据是会被拒绝的。只是为了方便描述和理解同源策略,实际上 Ajax 请求并不会被拦截。其背后 Ajax 请求跨域获取数据失败的真正原理是:浏览器禁止使用与当前网页不同来源的数据。当客户端浏览器向服务器发送跨域的 Ajax 请求时:(1)浏览器其实是发出了请求的、(2)请求也确实成功了,服务器也返回结果给客户端浏览器了、(3)但是因为响应结果中带着响应头,记录着数据来源的 IP 地址。所以,当浏览器查验服务端返回的数据时,发现响应头激活中的 IP 不是当前网页的 IP,就不会使用请求回来的数据。

问题 1:如果客户端电脑直接通过网址访问服务器,是不是就可以拿到数据了?答案是可以的,但是考虑到实际情况,一般不会出现这种情况的,因为基本上都是用户访问一个网站,在网站中做一些操作会发送一些服务器请求。

问题 2:为什么会出现跨域问题?现实情况中,为了保证项目的性能优化,和服务器的负载均衡,一般都会把服务器进行拆分几个部分:(1)web服务器:处理静态资源、(2)data服务器:做业务逻辑和数据分析、(3)图片服务器:专门为图片和视频等媒体资源设置一个服务器。如果这几个服务器的协议、域名、端口号有不同,就会导致了跨域的问题。

上一篇博客写到的 基于 JSONP 实现跨域 的方法虽然好,但是有一点缺陷就是,它只支持 GET 请求,不支持 POST 请求。如果需要支持 POST 请求怎么办,这个时候就需要用到 CORS 方式解决跨域了。

2、CORS 是啥

CORS 是一个 W3C 标准,全称是 "跨域资源共享"(Cross-origin resource sharing),它新增的一组 HTTP 首部字段,允许服务器声明哪些来源的请求有权访问当前资源,从而克服了 Ajax 只能同源使用的限制。

Ajax 请求跨域获取数据,服务器返回数据给客户端后,浏览器会用 CORS 策略查验服务器返回的数据,检查当前网页地址栏的地址是否等于返回数据的地址,如果两者不同,则浏览器就不会使用服务器响应给客户端的数据,并报错:"Access-Control-Allow-Origin" 的错误。

记住:response.setHeader('Access-Control-Allow-Origin','url') 。都得文档里,去看 MDN文档

3、CORS 的原理

基于 Ajax 请求跨域获取数据失败的真正原理是:浏览器禁止与当前网页不同来源的数据被使用CORS 的解决办法是,在服务端程序中,在发送消息之前手动修改响应头,将带有客户端浏览器的 IP 地址的数据包发送给客户端浏览器,然后客户端浏览器在查验服务端返回的数据时,发现响应头激活中的 IP 和当前网页的 IP 一样,那浏览器就认为这个数据包合法,可以使用该数据。代码如下:

//服务器端:服务器的地址为:127.0.0.1
const http = require("http");       //引入支持接受请求,返回响应的模块http
http.createServer((req,res) => {    //创建服务端程序实例,每当有客户端发来请求时,自动调用回调函数
    res.writeHead(200,{
        "Access-Control-Allow-Origin":"http://客户端网页地址栏中的地址";    //可以写 *,表示允许所有的跨域请求
    }),                                           //但是,如果写 *,就不允许请求中带cookie,目的是为了保证安全性
    var sentry = "这是客户端要的数据";
    res.write(sentry);
    res.end();
}.listen(3000);    //监听3000端口
 
//客户端:向服务器发送Ajax请求    --实际结果客户端并请求不到数据
$.ajax({
    url:'http://127.0.0.1:3000',
    type:"get",
    success:function(result){
        alert(result);
    }
})

4、CORS 的优缺点

CORS 和 JSONP 的优点与缺点大致互补,下面通过对比介绍两种跨域方式的优缺点:

(1)JSONP 只支持 GET 请求,不支持 POST 请求。但 CORS 支持 POST 在内的所有类型的 HTTP 请求。

(2)JSONP 相对于 CORS 的优势在于对浏览器的支持较好,虽然目前主流浏览器支持 CORS,但 IE10 以下不支持CORS

(3)CORS 相对于 JSONP 来说,前端需要做的事情比较少。而 JSONP 需要客户端和服务器都支持。

解释:为什么前端需要做的事情比较少,因为通过 JSONP 的方式实现跨域请求时,需要同时修改客户端和服务器的相关代码才能实现 Ajax 请求跨域获取数据的目的。而通过 CORS 的方式实现跨域请求时,只需要改写服务器配置的响应头即可。

(4)JSONP 只会发一次请求;而对于复杂请求,CORS 会发两次请求。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值