【读书笔记】Web开发中的跨域

文章:为什么给你设置重重障碍?讲一讲Web开发中的跨域

总结:

一、什么是跨域?

二、为什么不让跨域?

因为在web交互的环境中,只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的,

这就是跨站请求伪造(CSRF)

所以浏览器一定会设置跨域限制,避免在用户和网站不知情的情况下发出请求。

三、绕过跨域请求的方法?

(1)如果是子域名下的页面想访问父域的api,如zhuanlan.zhihu.com想访问zhihu.com的api,那可以在发请求前设置一下document.domain的值为zhihu.com。毕竟是子域,浏览器几乎没有做什么限制

(2)在非父子域关系的情况下,如zhuanlan.zhihu.comwww.zhihu.com(或者a.comb.com),就是被浏览器当作两个不同的域名的,一般就会使用JSONP了

JSONP本质上就是让数据变成js代码,使用script标签来加载数据。

因为浏览器并不限制script标签的src是要从哪里加载脚本,跨域问题似乎就被JSONP「绕过」了

JSONP实际上受限很大。作为一个script标签,一是浏览器只会使用GET方法去请求它,二是请求它的时候不会携带cookie,三是能被改造成JSONP形式的api一定是纯粹用来GET数据的。因此就算其他网站用这些JSONP改造过的接口,也不会对网站造成影响。

还有个缺点:确定jsonp的请求是否失败并不容易,大多数框架的实现都是结合超时时间来判定。

(所以后端开发者最好不要在GET操作里做非幂等的事,因为别人在他的网站里嵌入script或者img标签放你网站的url,浏览器就会发出一个不带cookie的GET请求)

(3)复杂的跨域需求——跨域资源共享(CORS)

四、跨域资源共享(CORS)

(1)简单请求(简单的GETPOST

zhuanlan.zhihu.com页面请求www.zhihu.com的api为例

  • Origin(发送请求)
  • Access-Control-Allow-Origin(响应请求)

1、浏览器发出请求的request里带上Origin头,值为zhuanlan.zhihu.com

2、响应api的header里带的Access-Control-Allow-Origin字段包含(匹配)zhuanlan.zhihu.com,浏览器就会认为合法,否则,浏览器会拦截掉这段数据:没错,响应的数据已经放body里到达了客户端,而浏览器会阻止掉,让负责发ajax的那段js代码拿不到响应值

好处很明显:我只需要在服务器端(通常是网关这一层)配置好Access-Control-Allow-Origin

(2)预检请求(如PUTDELETE等,或者请求时添加了CORS安全的header之外的header(如自定义的))

正式发送跨域请求前,浏览器会先对目标api发出一个OPTIONS预检请求,这个请求里会带三个和跨域相关的header,其值为预检之后,正式发送api请求时将会使用的来源/方法/请求头。这三个header是:

  • Origin(发送请求)
  • Access-Control-Request-Method(响应请求)
  • Access-Control-Request-Headers(响应请求)

预检请求的出现,是因为PUT等复杂操作通常是非幂等的。如果像简单请求一样直接请求,发现响应不合理才去拦截响应值,这个时候后端的PUT操作里该执行的事情已经被执行过了。

(至于为什么POST这个非幂等语义的方法会是简单请求,我觉得应该是历史包袱。毕竟在CORS出现前,form表单里POST就是能跨域使用的。而早期的js很弱小,提交form之后页面会刷新跳转到目标地址,源地址是拿不到POST响应的数据的)

(3)带cookie的请求

  • Access-Control-Allow-Credentials为true(响应请求)
  • Access-Control-Allow-Origin不能是通配符,防止后端开发者犯错(响应请求)

五、不让跨域请求?还可以直接跨网页

  • X-Frame-Options(响应请求)

猜你喜欢

转载自blog.csdn.net/lbbandcheng/article/details/81127271