You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过Accept Header区分AJAX与浏览器请求的策略是否可靠?

问题:区分AJAX与浏览器请求的Accept Header策略是否可靠?

我需要区分浏览器常规请求(比如HTML表单提交)和AJAX请求,目前观察到:

  • 常规HTML表单提交的请求头Accept值为:
    text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
    
  • 我自己写的AJAX请求(使用fetch)的Accept头明确设置为:
    application/json
    

对应的AJAX代码:

fetch("/auth/login", {
    method: "POST",
    headers: {
        "Accept": "application/json",
        "Content-Type": "application/json",
    },
    body: JSON.stringify({
        email: emailInput.value,
        pword: pwordInput.value,
    }),
});

基于这个差异,我在服务器端做了如下校验:

if (!req.headers.accept.includes("application/json")) {
    req.flash("loginError", "Please enable JavaScript or use a browser that supports JavaScript to continue.");
    return res.redirect("/auth/login");
}

现在有三个疑问:

  1. 这个策略在所有浏览器及版本中区分AJAX和浏览器请求是否可靠?
  2. 所有浏览器的常规请求Accept头格式是否一致?
  3. 会不会存在浏览器常规请求也包含application/json,导致校验失效的情况?

结论:这个策略不可靠,存在多种失效场景

1. 浏览器常规请求的Accept头没有统一格式

不同浏览器、同一浏览器的不同版本,常规请求的Accept头都会有差异。比如旧版Chrome和Firefox的Accept头会有不同的图片格式优先级,部分浏览器在特定场景下(比如页面加载过JSON资源),表单提交的Accept头可能会带上application/json。另外,浏览器扩展也可能修改请求头,让常规请求的Accept字段包含该值。

2. 确实存在常规请求包含application/json的情况

  • 安装了调试类、API相关的浏览器扩展时,这类工具可能会自动给所有请求的Accept头添加application/json;
  • 部分浏览器处理混合了HTML和JSON内容的页面时,表单提交的Accept头也可能包含application/json;
  • 用户可以通过开发者工具手动修改请求头,让常规表单请求带上该字段,直接绕过你的校验。

3. 更可靠的区分方案

如果要准确区分AJAX和常规浏览器请求,推荐以下几种方式:

  • 自定义请求头:在AJAX请求中添加一个自定义头,比如X-Requested-With: XMLHttpRequest(这是jQuery等框架的传统做法),服务器端校验这个头是否存在;
  • 通过Content-Type区分:AJAX请求你已经设置了Content-Type: application/json,而常规表单提交的Content-Type是application/x-www-form-urlencoded或multipart/form-data,可以通过校验这个字段来区分;
  • 分离路由:把AJAX请求和常规表单请求的路由分开,比如AJAX用/api/auth/login,常规表单用/auth/login,从根源上区分两种请求。

内容的提问来源于stack exchange,提问作者Oscar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 12:34:54