OPTIONS请求头是什么
在日常浏览网页时,你可能没注意到,浏览器其实在背后悄悄发过一种特殊的HTTP请求——OPTIONS请求。它不像GET或POST那样直接获取或提交数据,而是像一个“探路者”,先问问服务器:“我能不能这么干?”
这个请求通常出现在跨域场景中,比如你的前端页面运行在 http://a.com,却要访问 http://b.com/api 的接口。这时候浏览器出于安全考虑,不会立刻发送真正的请求,而是先发一个OPTIONS请求来“试探”服务器的态度。
为什么需要OPTIONS请求
想象一下你要进别人家门借东西,总得先敲个门问一句“方便吗?”,而不是直接推门进去。OPTIONS请求就是这声“敲门”。它属于CORS(跨域资源共享)机制的一部分,用来确认目标服务器是否允许当前来源的请求。
比如你用JavaScript调用了一个带自定义头的API:Authorization: Bearer xxx,或者发送的是JSON格式的数据,这种都算“非简单请求”。浏览器就会自动先发一个OPTIONS请求,带上一些关键的请求头,看看对方同不同意接下来的操作。
常见的OPTIONS请求头字段
在OPTIONS请求中,有几个常见的头部字段:
Access-Control-Request-Method: POST
Access-Control-Request-Headers: authorization,content-type
Origin: http://a.com这些字段告诉服务器:我待会要发一个POST请求,会带上authorization和content-type这两个头,我的页面来自a.com。你接受吗?
服务器收到后,如果同意,就会返回类似这样的响应头:
Access-Control-Allow-Origin: http://a.com
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: authorization,content-type
Access-Control-Max-Age: 86400这就相当于说:“行,你这个来源可以发这些方法,带这些头,有效期一天内不用再问了。”
OPTIONS请求什么时候不会出现
也不是所有跨域请求都会触发OPTIONS。如果只是普通的GET请求,且不带自定义头,Content-Type也是text/plain、application/x-www-form-urlencoded或multipart/form-data这类“简单类型”,浏览器就直接放行,不会多此一举发OPTIONS。
举个例子,你在网页里嵌入一个第三方图片或脚本,比如加载百度统计的js文件,虽然也是跨域,但因为是脚本标签发起的,且符合简单请求规则,就不会有OPTIONS。
开发中如何应对OPTIONS请求
作为开发者,尤其是写后端接口时,经常会遇到前端同学反馈“接口报错,预检失败”。这时候就要检查服务器有没有正确处理OPTIONS请求。
比如用Node.js的Express框架,可以这样加中间件:
app.use((req, res, next) => {
if (req.method === 'OPTIONS') {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.sendStatus(200);
} else {
next();
}
});这样就能让预检顺利通过,真正的请求才能继续执行。
有些Nginx配置也需要显式处理OPTIONS:
if ($request_method = OPTIONS) {
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
return 204;
}否则可能返回405 Method Not Allowed,让人一头雾水。
理解OPTIONS请求的作用,能帮你更快定位跨域问题。下次看到控制台里多了一个OPTIONS请求,别慌,它只是在替真正的请求“打前站”而已。