Next.js客户端如何获取HTTP请求的响应头数据?
问题原因
浏览器的CORS安全策略默认只允许前端JavaScript访问简单响应头(包括Content-Length、Content-Type等),其他自定义或非简单头需要后端服务器通过Access-Control-Expose-Headers响应头明确指定允许暴露的字段。
你之前在next.config.js中配置的headers是给Next.js自身的页面/API路由添加响应头,而你的请求是发给外部API服务器的,所以这个配置不会作用于目标API的响应,因此客户端依然无法获取额外的响应头。
另外,服务端渲染(SSR)时请求是在服务器端发起的,不受浏览器CORS策略限制,所以能正常获取所有响应头。
解决方案
方案1:控制后端API服务器时
直接在后端API的响应中添加Access-Control-Expose-Headers头,指定需要暴露给前端的响应头字段(多个字段用逗号分隔)。
比如使用Express框架的后端示例:
const express = require('express'); const app = express(); // 在全局中间件中设置CORS暴露头 app.use((req, res, next) => { // 替换为你需要获取的响应头,比如Date、X-Custom-Header等 res.header('Access-Control-Expose-Headers', 'Date,X-Custom-Header'); next(); }); // 你的API路由 app.get('/all-products', (req, res) => { res.setHeader('Date', new Date().toUTCString()); res.json({ products: [] }); }); app.listen(3001);
配置完成后,前端客户端就能通过response.headers获取到指定的响应头字段了。
方案2:无法控制后端API时
使用Next.js的API路由作为代理层:客户端先请求Next.js的API路由,由API路由在服务器端发起请求到目标API(不受CORS限制),再将需要的响应头和数据一起返回给客户端。
步骤1:创建代理API路由
在pages/api/proxy-products.js(Pages Router)或app/api/proxy-products/route.js(App Router)中添加以下代码:
Pages Router 示例:
import axios from 'axios'; export default async function handler(req, res) { try { // 发起请求到目标API const apiResponse = await axios.get(`${process.env.NEXT_PUBLIC_BASE_URL}/all-products`); // 提取需要的响应头(这里以Date为例,可根据需求添加其他头) const exposedHeaders = { date: apiResponse.headers.date, // 可添加其他需要的头,比如x-total-count等 }; // 返回数据和提取的响应头 res.status(200).json({ data: apiResponse.data, headers: exposedHeaders }); } catch (error) { res.status(error.response?.status || 500).json({ error: error.message }); } }
App Router 示例:
import axios from 'axios'; import { NextResponse } from 'next/server'; export async function GET() { try { const apiResponse = await axios.get(`${process.env.NEXT_PUBLIC_BASE_URL}/all-products`); const exposedHeaders = { date: apiResponse.headers.date, }; return NextResponse.json({ data: apiResponse.data, headers: exposedHeaders }); } catch (error) { return NextResponse.json( { error: error.message }, { status: error.response?.status || 500 } ); } }
步骤2:修改前端请求代码
将原来请求目标API的代码改为请求代理路由:
import axios from 'axios'; const api = axios.create({ // 客户端请求Next.js自身的域名,无需baseURL指向外部API baseURL: '', headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, }); const getProducts = async () => { const response = await api.get(`/api/proxy-products`); return { data: response.data.data, headers: response.data.headers }; }; export default { getProducts };
这样客户端通过代理路由就能获取到原本受CORS限制的响应头字段了。
内容的提问来源于stack exchange,提问作者aydosenes

