为何我的AJAX简单请求总是先发送预检请求?
为什么跨域GET请求会触发预检OPTIONS请求?
你遇到的问题核心在于:你以为的「简单请求」,实际上并不符合浏览器定义的简单请求标准,因此浏览器自动发起了预检请求。
浏览器判定「简单请求」的严格条件
只有同时满足以下所有条件,浏览器才会视为简单请求、跳过预检:
- 请求方法仅限:
GET、HEAD、POST - HTTP请求头只能包含以下允许的字段:
Accept、Accept-Language、Content-LanguageContent-Type(仅支持application/x-www-form-urlencoded、multipart/form-data、text/plain三种值)DPR、Downlink、Save-Data、Viewport-Width、Width
- 无自定义请求头,也未配置跨域凭证(
credentials)相关的特殊规则
你的请求触发预检的具体原因
使用$.get()发起请求时,jQuery默认会自动添加X-Requested-With: XMLHttpRequest这个自定义请求头——该头部不在浏览器允许的简单请求头列表内,因此浏览器判定这不是简单请求,必须先发送OPTIONS预检请求,确认服务器允许这个自定义头部后,才会发送实际的GET请求。
同样,若你使用fetch时未显式清除额外头部,或环境中存在默认添加的自定义头,也会触发相同的预检行为。
解决办法
若想让请求成为真正的简单请求、跳过预检,可尝试以下方式:
- 使用原生
XMLHttpRequest发起请求,手动控制请求头,不添加任何自定义字段 - 对jQuery请求配置,移除默认的自定义头部:
$.ajax({ url: 'http://127.0.0.1:8080/hello', method: 'GET', headers: { 'X-Requested-With': undefined // 移除jQuery默认添加的头部 } }); - 使用
fetch时,显式设置headers为仅包含允许的字段:fetch('http://127.0.0.1:8080/hello', { headers: { 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8' // 只保留浏览器允许的头部,不添加自定义字段 } });
内容的提问来源于stack exchange,提问作者n1nja88888
相关产品推荐
相关产品推荐

