我有一个react nextJS项目,代码如下:
import axios from "axios";
import config from '@/app/settings/config';
import { configConsumerProps } from "antd/es/config-provider";
export const instance = axios.create({
baseURL: 'localhost:8000',
timeout: 20000,
});
console.log(`Axios instance created with baseURL: ${instance.defaults.baseURL} and the config.host: ${config.host}` );
instance.interceptors.request.use( httpRequestConfig => {
//if login...
httpRequestConfig.headers['userId'] = '1'
// httpRequestConfig.headers.common['userId'] = '1' => result: (TypeError: Cannot set properties of undefined (setting 'userId'))
return httpRequestConfig
}, err => {
Promise.reject(err)
})
;
export default instance;
////THen in ansother place calls this code:
import instance from "@/lib/axios";
export default function Projects() {
useEffect(() => {
searchProjects(1)
}, []);
const searchProjects = (index: number, name?: string)=>{
instance.post('/api/v2/project/search', {
page_size: 20,
page: index,
// ...(config.debug ? { user_id: 1 } : {}),
...(name ? { name } : {}),
}).then((res)=>{
})
}
}
同时,我使用中间件设置了一个 python FastAPI 应用程序,目的是从请求标头中解析 userId。
from fastapi import Request
from fastapi import FastAPI, Request, status
from fastapi import applications
from starlette.middleware.base import BaseHTTPMiddleware
from fastapi.responses import JSONResponse
class UserIdValidationMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
try:
# Get user_id from header
header_user_id = request.headers.get("UserId")
if not header_user_id:
return JSONResponse(
status_code=400,
content={"code": 400, "message": "Missing user_id in request headers", "data": None}
)
response = await call_next(request)
return response
# Then in another file
app = FastAPI(
openapi_url="/openapi.json",
docs_url="/docs",
title="Orchestrator API",
description="Backend API for Chana Orchestrator",
version="1.0.0"
)
origins = [
"http://localhost:3000",
"http://127.0.0.1:3000",
"http://0.0.0.0:3000",
]
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
app.add_middleware(UserIdValidationMiddleware)
我在 python 中设置断点
request.headers.get("UserId")
使用curl来验证这个中间件是否有效。
对于react nextJS项目,我还在
httpRequestConfig.headers['userId'] = '1'
中设置了一个断点来验证标头是否已经设置。但这一次,python服务器指示标头中不存在userId。它收到的请求头是:
[(b'host', b'localhost:8000'),
(b'connection', b'keep-alive'),
(b'pragma', b'no-cache'),
(b'cache-control', b'no-cache'),
(b'accept', b'*/*'),
(b'access-control-request-method', b'POST'),
(b'access-control-request-headers', b'content-type,satoken,userid,xxxxx,yyy'),
(b'origin', b'http://localhost:3000'),
(b'user-agent', b'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'),
(b'sec-fetch-mode', b'cors'),
(b'sec-fetch-site', b'same-site'),
(b'sec-fetch-dest', b'empty'),
(b'referer', b'http://localhost:3000/'),
(b'accept-encoding', b'gzip, deflate, br, zstd'),
(b'accept-language', b'en-GB,en-US;q=0.9,en;q=0.8')]
那么react nextJS实例设置有什么问题呢?
最后,在阅读CORSMiddleware not work之后,这个问题得到了解决,它与CORS有关。它不在 axios 一侧。 添加中间件的顺序应该是
app.add_middleware(UserIdValidationMiddleware)
app.add_middleware(
CORSMiddleware,
allow_origins=origins,
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
如果顺序颠倒,则
UserIdValidationMiddleware
中无法获取自定义请求头