浏览器跨域详解

同源策略

浏览器为了安全考虑,如果一个网页访问一个协议,域名或者端口和自己不一样的资源,浏览器就会认证出现了跨域,包括img访问图片,script标签加载脚步等,但是对于这些跨域浏览器没有什么限制,其对ajax的跨域限制最为明显,要么浏览器不给对应的请求返回服务器的响应,要么就不发送对应的请求。常用的解决方案有三种:

  1. 代理
  2. CORS
  3. JSONP
代理

代理适用于跨域发生在开发环境中,在生产环境中没有跨域的情景。我知道的代理处理场景都是需要构建工具的参与的,以webpack为例:在构建webpack的时候,一般都是安装webpack-dev-server开发服务器,用于本地启动一个服务器运行我们编写的项目,在webpack.config.js中可以通过devServer配置需要代理的接口

CORS

如果通过CORS解决跨域问题,那么一般不需要前端的参与,因为这是浏览器和服务器的交互。
当一次请求是跨域请求的时候,浏览器会在请求头中自动添加origin请求头,表示这一次的请求源是谁。
cors处理跨域分为三类场景:

普通请求

只要满足一下条件就可以认为这次的请求是普通请求

  1. 请求方法为:get, post, head其中一种
  2. 使用的请求头都是安全的,没有自定义的请求头
  3. content-type的取值为:text/plain, application/x-www-form-urlencode, multipart/form-data中的一种
    如果本次请求是普通请求,那么服务器返回的报文中只需要携带Access-Control-All-Origin: 当前网页的源。那么浏览器就会认为服务器运行跨域访问就会将响应的报文返回给对应的请求。
    普通请求造成的跨域:
    在这里插入图片描述
    服务器设置Access-Control-Allow-Origin: http://127.0.0.1:8080:
    在这里插入图片描述
    成功获取到服务器的返回数据
    检查响应报文:
    在这里插入图片描述
    服务器明确表明了运行http://127.0.01:5173访问自己的资源,所以浏览器就没有拦截响应的报文了
    服务器也可以通过设置Access-Control-Allow-Origin: * 表示任何网站都可以访问我的资源,但是当请求携带cookie的时候,*的写法不会通过浏览器的校验,浏览器就不会发送对应的请求。
预检请求

不是普通请求就是预检请求,当一个请求是预检请求的时候,浏览器不会立即发送这次的请求,而是会先构建一个报文,询问服务器是否允许这样的请求发送给它。浏览器的控制台不会显示预检请求的记录,只能通过服务器查看:
在这里插入图片描述
预检请求的请求方式Options,通过会在请求头中携带跨域请求的请求方法,由于造成本次请求不是普通请求的原因是,请求的方法为put,所以请求头通过Access-Control-Request-Method: PUT, 询问服务器是否允许put请求进行的跨域访问,如果不允许,那么浏览器就不会发送这一次的请求,同时抛出错误。
在这里插入图片描述
如果服务器运行对应的请求方式进行跨域访问,那么可以在响应报文中设置Access-Control-Allow-Methods: 请求方法,注意这里是Methods。浏览器收到报文以后,就会发送对应的报文,服务端代码:
在这里插入图片描述
如果是由于携带了特殊的请求头造成的预检请求,那么在预检请求的请求头中还会携带,Access-Control-Request-Headers: 对应的请求头,这里由于是添加了自定义的请求头auth,所以值为auth。
在这里插入图片描述
如果有多个不安全的请求头,Access-Control-Request-Headers为这些请求头的集合:
在这里插入图片描述
同理如果服务器运行携带这些请求头的请求访问自己,那么只需要在返回的报文中携带:Access-Control-Allow-Headers: 对应的请求头即可。
在这里插入图片描述
如果不想没有发起跨域请求是都先发一次预检请求,那么服务器可以设置响应头Access-Control-Max-Age,表示在多少以内,同样的源发起的请求可以不发生预检请求了。
未设置前发起请求:
在这里插入图片描述
每一次都会触发预检请求,设置Access-Control-Max-Age以后:
在这里插入图片描述
注意不是所有的浏览器都支持Access-Control-Max-Age, 有些浏览器即使设置了Access-Control-Max-Age,该触发预检请求还是会触发预检请求。上面的成功实例是在edge浏览器中实现的。

携带cookie的请求

当携带cookie以后,这个请求就一定会触发预检请求,服务器必须明确指定Access-Control-Allow-Origin 为跨域站点的源,不能是*号。
在fetch请求中设置请求的时候携带cookie:
在这里插入图片描述
虽然我在响应报文中指定了允许http://127.0.0.1:5173源,通过put请求携带a,auth,和b请求头,跨域访问服务器,但是浏览器依然没有运行本次请求发送处理,并触发跨域异常。
在这里插入图片描述
在这里插入图片描述
警告已经明确的告诉我们,响应还需要携带Access-Control-Allow-Credentials为true的请求头。
在这里插入图片描述
通过设置Access-Control-Allow-Credentials 为true,请求就能正常获取数据了。

补充

虽然通过设置

  1. Access-Control-Allow-Origin:指定运行跨域访问的源
  2. Access-Control-Allow-Methods: 指定运行跨域访问的请求方法
  3. Access-Control-Allow-Headers: 指定跨域访问可以携带的请求头
  4. Access-Control-Allow-Credentials: 指定是否允许携带cookie进行跨域
    通过上述字段,可以得到其他源的数据,但是浏览器仍然不放心,所以浏览器并不会将所有的响应头都暴露个js,比如服务器自定义的响应头:
    在这里插入图片描述
    在浏览器中通过js获取响应头,并打印出来:
    在这里插入图片描述
    没有得到服务器自定义的响应头。
    此时如果服务器运行浏览器获取相应的响应头,那么需要返回另一个响应头:Access-Control-Expose-Headers,指定需要暴露给浏览器的响应头
    在这里插入图片描述

在这里插入图片描述
此时对应的js请求就能得到相关的响应头了。

  • 24
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要配置Nginx实现浏览器跨域访问,可以按照以下步骤进行配置: 1. 在Nginx服务器上创建一个目录用于存放跨域访问资源。可以使用命令`mkdir /usr/share/nginx/corsmulti02/`来创建目录。 2. 在创建的目录中创建一个index.html文件,并添加内容。可以使用命令`echo '<h1>Corsmulti02</h1>' > /usr/share/nginx/corsmulti02/index.html`来创建文件并添加内容。 3. 在Nginx的配置文件中添加跨域访问的配置。可以使用add_header语法来配置响应头,使多个域名能够跨域访问资源。例如,可以在配置文件的相应位置使用以下语法进行配置: ``` add_header Access-Control-Allow-Origin "http://localhostsource01.odocker.com"; add_header Access-Control-Allow-Origin "http://source02.odocker.com"; ``` 其中,将"http://localhostsource01.odocker.com"和"http://source02.odocker.com"替换为允许跨域访问的域名。 通过以上配置,就可以实现浏览器跨域访问Nginx服务器上的资源了。在浏览器中访问"http://corsmulti02.linuxds.com/"即可跨域访问Nginx服务器上的资源。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Nginx跨域配置](https://blog.csdn.net/m0_67391683/article/details/126113742)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Nginx跨域访问场景配置和防盗链详解](https://download.csdn.net/download/weixin_38737335/14091819)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值