跨域HTTP预检请求、嗅探请求、options请求的解决优化办法

 前言:这篇文章没有涉及到基础的协议内容,大部分是开发中会遇到的一些问题。鉴于最近开发遇到一些问题,解决了感到很兴奋,也解决了我去年开发中自己遗留下的疑惑。偷得浮生半日闲,我写这篇文章,目的是为了方便大家理解理论与实际开发中的场景,更快地定位问题,解决开发中遇到的一些问题。

 

一、什么是HTTP协议

叫做超文本传输协议,他基于TCP/IP协议基础上做传输(知道这个概念就可以)。可以看下我之前在网上看过一张很经典的图:

 

可以简单理解为:在  发送端  和 接收端  之间的这个超文本解析方式协议就是HTTP协议

 

为了通俗易懂我这里把他拆出来,先在linux上面讲解。因为不管是浏览器还是linux传输这个都是依据http协议。

1、首先通过linux的 curl 命令来请求接口:

curl   -v   https://blog.csdn.net/phoenix/web/v1/comment/template/List

 

 如上图所示:任何请求都会有我上面表明的这几个内容。

那么linux是怎么知道哪个是响应头,哪个是响应内容呢,就是根据换行符来决定的。仔细看上面的请求部分、响应头、响应内容,都有个换行,linux就是根据这个识别的,那么可以推测浏览器也可能是根据这个来识别。当然浏览器展示的更直观。

二、请求中为什么会遇到跨域请求

首先要明确一点的是,跨域请求实际上是浏览器进行拦截的。(浏览器的安全策略拦截)你通过linux的curl去请求接口是怎么也不会遇到跨域。所以跨域实际出现一般都是前后端分离场景。

1、什么是跨域请求,就是同一资源,请求别的域资源。简而言之域不同:包括3种情况。

有的人会有疑问是什么域?看下面截图,就是浏览器url地址和请求的url。只要这两个地址有以下任何一个不同就会出现跨域

  • 协议不同,http协议  和  https协议
  • 端口不同,(截图所示就是端口不同,url上面的默认端口为80,请求地址的为7179,所以这里跨域了)
  • 域名(ip)不同,www.baidu.com 和 www.a.com   (包括ip和域名,若一个是ip一个域名也会跨域,即使该域名指向该ip)

 

、跨域如何解决

一般常用有两种种:前端nginx、后端设置cros允许跨域。(完全够用)

开发中可以在项目中设置proxy代理。通过特定标识符号,例如   /api   来进行代理。

解决跨域比较简单,这里不详细说明。但是有时候会遇到比较特殊的情况,可以看下这篇文章:

https://blog.csdn.net/weixin_40910372/article/details/100068498

四、为什么每次会有options请求

options(预检/嗅探请求)可能会导致请求变慢,每次进行接口请求时候,浏览器会先发出一个options请求,然后才发起正式的请求。

那么为什么会有options请求呢,导致它的原因是:在cros跨域请求下浏览器将请求分为两种:1、简单请求,2、非简单请求(复杂请求),在非简单请求下,就会有options请求。

   简单请求:(属于以下几点的就是简单请求,其他的都是非简单请求)

  • 请求方式有且只限于:GET、POST、 HEAD
  • 请求头不超出以下字段(且没有其他自定义字段):
    Accept
    Accept-Language 
    Content-Language
    Last-Event-ID
    Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain

解决办法(优化):可以通过设置响应头部的  Access-Control-Max-Age  来设置预检请求有效期,即在设置的时间内只有第一次会发送出数据,下次这个接口请求(相同接口&相同参数时)不会再发出这个预检请求,而是发送真请求

  方法1、通过nginx添加响应头

location /test/ {
add_header ‘Access-Control-Max-Age’ 600;
proxy_pass http://a**********/;
}

  方法2、后端直接设置这个响应头并设置时间

 

  注意:在Chrome浏览器在debug状态,或者勾选上Disable cache,这个配置将失效。

 

posted @ 2020-10-12 14:24  月亮出来了  阅读(3062)  评论(0编辑  收藏  举报