如何在 Fetch(JavaScript)中设置 Host Header
Source: Dev.to
(请提供需要翻译的正文内容,我将为您翻译成简体中文。)
快速解决方案
使用 Corsfix 在前端代码中设置 Host 请求头。将你想要的请求头放在 x-corsfix-headers 中,Corsfix 会在服务器端应用它,然后再转发你的请求。
fetch("https://proxy.corsfix.com/?https://api.example.com/data", {
headers: {
"x-corsfix-headers": JSON.stringify({
Host: "api.example.com",
}),
},
})
.then((response) => response.json())
.then((data) => console.log(data));
Corsfix 接收你的请求,将 Host 请求头设置为你指定的值,并将请求转发到目标 URL。随后,响应会带着正确的 CORS 头返回到你的浏览器。
对于本地开发,这种方式可以立即使用,无需注册。对于正式站点,请 设置你的域名(约 30 秒)。
为什么浏览器阻止 Host Header
Host 头是浏览器的 forbidden header names 列表之一。浏览器会自动管理这些头部,并且不允许 JavaScript 对其进行修改。Host 头告诉服务器请求针对的是哪个域名,浏览器会根据你请求的 URL 自动设置它。
在像 Node.js 这样的服务器端环境中,你可以完全控制所有头部,包括 Host:
// Node.js — 这可以正常工作
const response = await fetch("https://api.example.com/data", {
headers: {
Host: "custom-host.example.com",
},
});
在浏览器中,这个头部会被静默忽略:
// 浏览器 — 这会被忽略
fetch("https://api.example.com/data", {
headers: {
Host: "custom-host.example.com", // 被浏览器忽略
},
});
浏览器始终使用 URL 中的主机名,这也是需要使用代理的原因。
代理如何解决该问题
由于浏览器不允许直接设置 Host 头,代理可以为你完成此操作:
- 你的浏览器向 Corsfix 发送请求,包含目标 URL 以及要在
x-corsfix-headers中覆盖的头部信息。 - Corsfix 读取覆盖指令,在外发请求上设置实际的
Host头,然后将请求转发到目标 API。 - 目标 API 收到的请求中包含了你指定的
Host头部值。
何时需要设置 Host Header?
在实际场景中,控制 Host 头部很重要的情况包括:
- 虚拟主机 – 服务器在同一 IP 上托管多个域名,并使用
Host来路由请求。 - API 网关 – 某些网关会验证
Host头部,若值不匹配则会拒绝请求。 - 网页抓取 – 某些站点会将
Host作为机器人检测逻辑的一部分进行检查。 - SNI 与 TLS 路由 – 负载均衡器可能会使用
Host来选择正确的 TLS 证书。
最佳实践
仅覆盖必要的内容
不要在每个请求中都覆盖 Host 头。仅在目标 API 明确要求特定 Host 值时才使用它。在大多数情况下,默认行为(使用 URL 中的主机名)是正确的。
优雅地处理错误
如果 Host 头与服务器期望的不匹配,可能会收到以下错误:
403 Forbidden– 服务器拒绝了Host值。421 Misdirected Request–Host与服务器不匹配。502 Bad Gateway– 上游服务器无法路由该请求。
错误处理示例:
const response = await fetch(
"https://proxy.corsfix.com/?https://api.example.com/data",
{
headers: {
"x-corsfix-headers": JSON.stringify({
Host: "custom-host.example.com",
}),
},
}
);
if (!response.ok) {
console.error(`Request failed: ${response.status}`);
}
结论
使用类似 Corsfix 的服务器端代理在 JavaScript fetch 中设置 Host 请求头。由于浏览器将 Host 视为受限的 forbidden header name,代理是最简单的方式来覆盖它,而无需自行构建后端。Corsfix 在服务器端处理 Host 请求头的覆盖(以及其他 forbidden headers),让你专注于应用本身,而不是代理基础设施。它提供免费入门选项,生产环境可选升级。