浏览器的预检请求 -- options

一、简介

HTTP OPTIONS请求用于描述目标资源的通信选项,主要用途有:

1、CORS(跨来源资源共享) 预检请求。

在CORS场景中,当客户端尝试使用非简单请求(如PUT、DELETE、带有自定义头的POST请求等)访问跨域资源时,浏览器会首先发送一个OPTIONS请求到服务器,以检查服务器是否允许该跨域请求(如:当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段)。
服务器在收到OPTIONS请求后,会返回一个包含CORS相关响应头的响应,告知客户端是否允许该跨域请求。

补充1:
(1)简单请求:
a、请求方法是以下三种方法之一:

  • HEAD
  • GET
  • POST

b 、HTTP的头信息不超出以下几种字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

(2)非简单请求

非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT或DELETE,或者Content-Type字段的 类型是application/json。

补充2:
对于每个非简单请求,浏览器都会发送一个预检请求。但是,如果浏览器已经知道服务器的CORS策略(例如,通过之前的简单请求获得),并且这个策略对于当前的非简单请求是有效的,那么浏览器就不需要再次发送预检请求。
预检请求结果会缓存。

会返回204。响应的报文中不含实体主体。
在这里插入图片描述

2、网络调试。

开发人员可以使用OPTIONS请求来测试服务器对特定资源的支持情况,以及获取有关服务器配置和能力的信息。

二、背景和问题

1、背景
在服务器等保三级审核时间有限的背景下,为满足客户对平台服务器的等保要求,使用了一个已经审核通过的服务器用nginx做了反向代理。
2、问题

微信公众号软件无法绑定用户,请求接口一直报错,但通过postman访问接口却可以成功。

三、环境搭建及问题解决

1、 找服务器安装一个nginx,在服务器开放端口

image.png

2、 配置反向代理
server {
    listen       9998;
    server_name  localhost;

		#add_header 'Access-Control-Allow-Origin' '*';
		#add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
		#add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
   	
		location /amiwatergas113/ {
			# add_header 'Access-Control-Allow-Origin' '*';  # 或具体源地址  
			# add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';  
			# add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization,lang';  
      proxy_pass https://xxxxxxx.com/api/;
      proxy_set_header        Host $host;
      proxy_set_header        X-Real-IP $remote_addr;
      proxy_connect_timeout   90;
      proxy_send_timeout      90;
      proxy_read_timeout      90;
      proxy_buffer_size       4k;
      proxy_buffers           4 32k;
      proxy_busy_buffers_size 64k;
      proxy_temp_file_write_size 64k;
      proxy_set_header X-Forwarded-For   $proxy_add_x_forwarded_for;
      proxy_redirect          off;
    }

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }

        
}
3、 问题复现
(1)options请求 缺少请求属性 CORS Missing Allow Origin

搭建完环境,配置完反向代理直接运行nginx,通过前端代码访问中间服务器的代理地址。

![image.png](https://img-blog.csdnimg.cn/img_convert/92dd4aef9112f078fa33f61d150688fb.png

结果:
image.png

在这里插入图片描述

在这里插入图片描述

(2)options请求 Access-Control-Allow-Headers 缺失

我们把Access-Control-Allow-Origin 属性加上,重启nginx,并前端请求
##### ![image.png](https://img-blog.csdnimg.cn/img_convert/2551227ff96d55aef127d9236a99c109.png)

结果:

在这里插入图片描述

(3)post请求头信息重复配置,但options请求通过了

此时,我们把所有的跨域请求的nginx配置加上。重启nginx。

在这里插入图片描述

结果:预检请求通过了,但post请求提示请求信息重复配置

在这里插入图片描述

(4)options请求 缺少请求属性 CORS Missing Allow Origin

所以我们把这个 多的请求信息注释掉

在这里插入图片描述

重启nginx运行后,请求发现又回到了第一种情况

在这里插入图片描述

(5)最终版

当时卡在这个地方很久,现在回头来看,就是options请求缺失了Access-Control-Allow-Origin 配置,
而 post请求并不需要这个配置。所以加一个判断就可以了。

在这里插入图片描述

结果:
接口请求成功

在这里插入图片描述

Nginx 的配置中,if 语句可以用来根据条件执行不同的配置块,但是 它的 if 语句的行为与其他编程语言或脚本语言中的 if-else 有所不同,它不直接支持 else 子句,是通过在 if 语句外部定义其他配置来隐式地实现“否则”的逻辑。

四、其他

补充1:location和proxy_pass

(1) proxy_pass后的URL 无 /

location /xxx {    
    proxy_pass http://backend.example.com;     
    # 其他指令...    
}
  • 没有尾部斜杠:如果 proxy_pass 后面的 URL 没有尾部斜杠,并且请求的 URI 包含尾部斜杠(如 /xxx/),则 Nginx 会将请求转发到 http://backend.example.com/xxx/(即保留原始 URI)。如果请求的 URI 没有尾部斜杠(如 /xxx),Nginx 会将其转发为 http://backend.example.com/xxx(去除 Nginx 中的 URI 末尾的斜杠,如果存在的话)。
  • 有尾部斜杠:如果 proxy_pass 后面的 URL 包含尾部斜杠(如 http://backend.example.com/),则 Nginx 会将请求 URI 中与 location 指令匹配的部分替换为空字符串(即去除这部分 URI),并将剩余的 URI 部分附加到 proxy_pass 指定的 URL 后面。
补充2:

image.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值