本文根据MDN整理

我不说什么是跨域,网上很多,但是要说一下,跨域访问控制这个概念,是浏览器的行为,不是服务器的行为(虽然不少工作都是后端的工程师去配置),产生跨域访问控制的原因有两个:
1.前端发出跨域请求,浏览器发现是跨域请求,拦截该请求
2.前端发出跨域请求,跨域请求正确发送出去,当服务器返回数据给浏览器的时候,浏览器发现是跨域请求,则将服务器返回的结果拦截,此时,前端工程师应该会发现not found response的相关错误信息
综上所述,跨域访问控制是浏览器的行为

随着越来越多的前后端分离项目兴起,所以HTTP新增了一组适用于跨域的头部字段,以及一个叫做OPTION的交互机制,规范要求,除了简单请求,浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。

承接上个自然段,符合下面3个条件的HTTP请求叫做简单请求,它们不会产生跨域访问控制(CORS)
条件1. 请求方法必须是下面三个中的一个
GET,HEAD,POST
条件2. 请求头中的每一个字段必须是下面9个中的一个
Accept
Accept-Language
Content-Language
Content-Type
DPR
Downlink
Save-Data
Viewport-Width
Width
条件3. 若请求头中包含Content-Type,则Content-Type属性必须是下面3个中的一个
text/plain
multipart/form-data
application/x-www-form-urlencoded

下面是一个最简单的访问控制请求头,这个请求会出现跨域,因为Origin不满足条件2
对于request

Origin:https://shiwentian.cn

对于response

// 此处注意这个星号,对于Credentials特性,此处星号有说道,一定要注意
Access-Control-Allow-Origin:*

上面的response表示当前request请求的资源可以被任意外域访问,而不只是https://shiwentian.cn,如果response中的返回值是下面这样

Access-Control-Allow-Origin:aa.com

则表示该资源只允许域名是aa.com的请求访问

通过Origin与Access-Control-Allow-Origin,完成了最简单的访问控制

预检请求(preflight request)
我个人理解"预检"的意思就是,预先检查当前请求中,不属于上文描述的简单请求的那一部分属性,是否被服务器支持,比如下面的例子中,Abc这个属性就是不属于简单请求,并且,GLJ属性也不属于简单请求,所以预检请求会询问服务器,是否支持Abc,以及Content-Type中的GLJ属性,request如下

GET /resources/public-data/ HTTP/1.1
Abc:MYS
Content-Type:GLJ
Origin: http://shiwentian.cn

虽然该请求是GET请求,符合简单请求中的条件1,但是由于header中有一个我自定义的属性Abc,不符合简单请求中的条件2,而且Content-Type中的GLJ也不符合简单请求中的条件3,所以该请求发起之前,浏览器会先发送一个预检请求,浏览器发送的预检请求如下

GET /resources/public-data/ HTTP/1.1
Abc:MYS
Origin: http://shiwentian.cn
Access-Control-Request-Method: GET
Access-Control-Request-Headers: Abc, Content-Type

该预检请求询问服务器:“我这个头部有Abc的属性,并且媒体类型是Content-Type似乎有些特殊,你告诉我你支持什么类型,然后我这边判断一下,看看是否支持这两个类型”
此时服务器收到浏览器的问询,则服务器返回的response格式如下

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://shiwentian.cn
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: Abc, Content-Type
Access-Control-Max-Age: 86400
Content-Type: text/plain

这个返回的意思一看就明白了,表示服务器告诉浏览器"我目前支持POST, GET, OPTIONS方法,关于自定义的请求头目前支持Abc,关于自定义的媒体类型支持text/plain,我这个回答有效期是86400秒,也就是24小时,你24小时之内发送跨域请求的时候不要在问我了,好烦…"

此时,浏览器发现Content-Type:GLJ不等于Content-Type: text/plain,则会从控制台告知前端开发人员,出现跨域问题,

文章至此,大部分关于访问控制的内容已经描述完毕,下面来说访问控制的另外一个我个人认为已经过时的特性-附带身份凭证

附带身份凭证(Credentials)
之所以我说Credentials过时,是因为它基于cookie,因为cookie过时,下面是使用XMLHttpRequest对象向shiwentian.cn发送一个GET实际请求(注意不是OPTIONS预检请求

var invocation = new XMLHttpRequest();
var url = 'http://shiwentian.cn';function callOtherDomain(){if(invocation) {invocation.open('GET', url, true);invocation.withCredentials = true;//注意这里invocation.onreadystatechange = handler;invocation.send(); }
}

上述代码实际生成的request如下

GET /shiwentian.cn/ HTTP/1.1
Origin: http://shiwentian.cn
Cookie: name1=mys

注意withCredentials=true,表示发送请求的时候,附带cookie,此时,如果服务器端的响应response中未携带头部消息 Access-Control-Allow-Credentials: true ,浏览器将不会把响应内容返回给请求的发送者,所以服务端的response返回格式应该如下,这样浏览器才不会拦截response

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://shiwentian.cn //注意这里不是星号
Access-Control-Allow-Credentials: true //response中必须带这个

下面注意,注意,注意
对于附带身份凭证的请求(Credentials),服务器不允许设置 Access-Control-Allow-Origin 的值为星号"*",这是因为请求的首部中携带了 Cookie 信息,如果设置成星号,请求将会失败

综上所述,我个人强烈不要使用cookie这种过时的http头部属性

好了,文章到此结束,如果你需要查看更多详细信息,请点击这里,因为本文就是基于该文档来写的

网络-HTTP请求跨域访问控制相关推荐

  1. 浏览器跨域访问控制(CORS)

    一. 什么是跨域? 出于安全考虑,浏览器限制页面脚木发起跨域请求,所以XMLHttpRequest和fetch API是遵循同源策略的. 例如,在http://domain-a.com 页面用XMLH ...

  2. Tomcat中的字体请求跨域问题解决

    Tomcat中的字体请求跨域问题解决 原作者地址: https://blog.csdn.net/u011974399/article/details/79990505 修改tomcat的web.xml ...

  3. ajax跨域访问控制

    ajax跨域访问控制 转载于:https://www.cnblogs.com/macT/p/10214014.html

  4. 关于vue-cli3中配置请求跨域的问题

    关于vue-cli3中配置请求跨域的问题 根据Vue CLI3官方文档, 需要在vue.config.js文件中配置devServer.proxy选项来解决跨域问题. 1.关于vue.config.j ...

  5. SpringMVC中的异步请求-跨域访问

    发送异步请求: <%@page pageEncoding="UTF-8" language="java" contentType="text/h ...

  6. 关于ajax post请求跨域问题的解决心得

    关于ajax post请求跨域问题的解决心得 参考文章: (1)关于ajax post请求跨域问题的解决心得 (2)https://www.cnblogs.com/guaishushulz/p/670 ...

  7. React项目中请求跨域解决方法

    React项目中请求跨域解决方法 今天经理给我了一个React项目地址,让我拉下来并跑起来,拉下来运行起来后,发现所有的请求都失败了,并且都是由于跨域问题导致的.花了点时间,解决了这个问题,在这里记录 ...

  8. 解决POST请求跨域问题

    解决POST请求跨域问题 今天在做项目的时候.出现了POST请求跨域失败,而GET请求跨域成功的很奇怪的情况,自己为此研究了好久,特此做个记录. 场景:前端发起POST请求后端接口时,报错,错误如下: ...

  9. WebApp开发:ajax请求跨域问题的解决

    WebApp开发:ajax请求跨域问题的解决 参考文章: (1)WebApp开发:ajax请求跨域问题的解决 (2)https://www.cnblogs.com/code-style/p/42094 ...

最新文章

  1. python语言用途-Python是万能的编程语言吗?这五大用途很重要!
  2. 局域网无法访问本地apache
  3. SRM 591 div1 275
  4. Spyder常用快捷键
  5. 告别ASP.NET操作EXCEL的烦恼(总结篇)
  6. python有关迭代器和生成器的面试题_python面试题之生成器迭代器
  7. SpringCloud SpringBoot mybatis分布式微服务云架构开发Web应用
  8. 如何简洁优雅地实现Kubernetes的服务暴露
  9. 联想重装系统去掉保护_联想硬盘保护系统,小编教你联想硬盘保护系统怎么用...
  10. 调节e18-d80nk的测量距离_没有倒车影像,用这个方法判断后方墙壁距离,这个距离感这样练习...
  11. Vue引用百度地图API
  12. Servlet和JSP小结
  13. 守望者的逃离 动态规划+滚动数组
  14. Matlab 动态心形线GIF图
  15. CentOS 8上安装Docker
  16. 理解为什么女孩子都希望进国企了
  17. java 鉴黄_真香,我把百万鉴黄服务源码开源了
  18. 微信再次改版!这个功能终于要下线
  19. vertical-align的用法
  20. 【2022 Twitter爬虫高级搜索接口分析及代码编写 Python爬虫 附主要代码及解析】

热门文章

  1. 引入SpringBoot Jpa依赖后,项目出现警告
  2. php mescroll,mescroll.js上拉加载下拉刷新组件使用详解
  3. mysql数据库主从不同步_MySQL数据库之mysql主从数据库不同步的2种解决方法
  4. canvas转化为图片并下载
  5. (转)tomcat配置访问项目时不需要加项目名称
  6. 计算机中 amp 是什么符号,这里面的amp;amp;,||是什么意思,相当与数学里面的什么符号?...
  7. hannoi塔java程序_基于Java实现的Hannoi汉诺塔自动演示程序
  8. 摄像头 保存到外网服务器_直播平台搭建千万不要忽略流媒体服务器的存在
  9. vue引入如何使用不同字体
  10. Centos7 安装python3.7.0