Flutter web 踩坑关于浏览器的跨域的深思

1.由于浏览器有同源策略,(相同协议,相同ip,相同端口)才能访问,由此导致出现跨域问题

2.跨域的解决方法常见的有Jsonp, 以及nginx代理

3.问题:1.禁止跨域到底是浏览器禁止的,还是服务器拒绝的 2.如果Nginx代理网站后,为什么访问Nginx代理的端口的就不会出现跨域呢(Nginx端口肯定也是独立的啊)

4.问题:为什么跨域请求有时候会有两次请求,其中一次是optin,请求然后才是正确的请求

 解答:

关于上边的问题解答如下:

2.1.跨域jsonp解决方案是利用script 标签支持跨域加载,但是script 都是通过get请求,因此josnp 发送的都是get请求,因此无法post数据

2.2 nginx 代理能解决跨域是因为:向代理服务器的nginx发起请求时候,nginx的配置中响应头中允许了跨域请求(即增加响应头:'Access-Control-Allow-Origin', '*'),然后nginx 收到请求后会通过代理的请求方式向目标服务器发器请求,然后将数据返回给客户端,从而解决了跨域问题

3.1 :跨域是浏览器通过拦截禁止的,跨域请求发生后,服务器端可以收到跨域的请求并能返回正确的数据,但是如果服务器端未设置允许跨域,则浏览器收到数据时候发现不允许跨域请求,那么浏览器就会拦截数据,并在控制台中说明是因为同源策略请求失败的

3.2答案在2.2中

4.在跨域请求中:浏览器默认会分为简单请求和复杂请求,简单 请求会直接请求服务并返回数据,复杂请求则浏览器先发送 optin请求,然后服务器端响应如果允许则会发器后续请求,如果服务器不响应或者拒绝,则不会发器后续请求

其中简单请求要求如下:

请求方法是以下三种方法之一:
  • HEAD
  • GET
  • POST
HTTP的头信息不超出以下几种字段:
  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

复杂请求发起流程如下:

例如:post请求需要自定义请求头 ,增加请求头signature ,和user

那么此时浏览器会发起optin 请求,会携带如下请求头

access-control-request-headers: signature ,user
access-control-request-method: POST、

其中access-control-request-headers 是告诉服务器,客户端想自定义请求头

access-control-request-method:  是告诉服务器请求通过什么样方式发出

然后服务器响应:服务器需要响应的响应头中需要有如下信息

"Access-Control-Allow-Methods", '*' ; //跨域预检请求时候允许的请求方式,*则是任意请求方式,也可以指定请求头中的access-control-request-method的值
"Access-Control-Allow-Headers", "*" ;//允许跨域自定义的请求头,*则是任意请求头都可以,也可以指定请求头中的 access-control-request-headers的值
"Access-Control-Allow-Credentials", true //,如果服务器端的响应中未携带 Access-Control-Allow-Credentials: true ,浏览器将不会把响应内容返回给请求的发送者。
"Access-Control-Max-Age", "3600" //跨域时候预检周期,防止重复性预检,即该请求在3600秒以内,不会进行预检了(周期内不进行optin 请求)

本文参考了该片文章,该文章对跨域解释很明确感谢:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

 


 
posted @ 2020-08-26 13:50  烟花易冷心易碎  阅读(2835)  评论(0编辑  收藏  举报