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

Node.js服务端调用req.header()无法获取指定请求头值异常排查

问题说明

本问题关联此前遇到的JsonWebTokenError: jwt must be a string报错:在Node.js服务端执行console.log(req.header('host'),'req host')读取host请求头时,打印结果和直接打印req得到的完整请求对象一致,无法正常读取请求头指定字段,已配置CORS允许自定义请求头访问但问题未解决。

相关代码

前端Post.js(发起POST请求携带请求头)

import React, { useEffect, useState } from 'react'
import { useParams } from 'react-router-dom';
import axios from 'axios';
import './Post.css'


function Post() {

    let { id } = useParams();

    const [postObject, setPostObject] = useState({})
    const [comments, setComments] = useState([]);
    const [newComment, setNewComment] = useState("");

    const addComment = () => {
        const accessToken = sessionStorage.getItem('accessToken')
        console.log(typeof (accessToken), 'acces token in comment button')

        axios.post(`http://localhost:4000/comments`, {
            commentBody: newComment,
            PostId: id
        },
            {
                headers: {
                    accessToken: accessToken,
                }
            }
        )
            .then((res) => {
                const data = res.data;
                console.log(data, 'comments')
                setComments([...comments, data])
                setNewComment("")
            })
            .catch((err) => {
                alert(err, 'Error:comment')
            })
    }

    return (
        <div className='Post'>
            <div className='left__side'>
                <div className='left__side__wrapper'>
                    <div className='title'>{postObject.title}</div>
                    <div className='text'>{postObject.postText}</div>
                    <div className='username'>{postObject.username}</div>
                </div>
            </div>
            <div className='right__side'>
                <div className='right__side__wrapper'>
                    <div className='add__comment__container'>
                        <input type="text"
                            value={newComment}
                            placeholder="Comment"
                            onChange={(e) => setNewComment(e.target.value)}
                        />
                        <button onClick={addComment}> Submit Comment</button>
                    </div>
                    <div className='listOfCommnets'>
                        {comments.map((item, index) => {
                            return <div className='comments' key={index}>Comments:<br />{item.commentBody}</div>
                        })}
                    </div>
                </div>
            </div>
        </div>
    )
}

export default Post

后端AuthMiddleware.js(接收请求头的中间件)

const { verify } = require("jsonwebtoken")

const validateToken = (res, req, next) => {
    console.log(req, 'req')
    console.log(req.header('host'), 'req host')
}

module.exports = { validateToken }
问题根因

Express 中间件的形参顺序是固定的,必须按照 (请求对象Request, 响应对象Response, next回调) 的顺序定义。你当前中间件写的形参顺序是(res, req, next),导致:

  • 形参名res实际接收到的是真实的请求对象
  • 形参名req实际接收到的是真实的响应对象

响应对象本身没有读取请求头的header()方法,调用时自然返回不符合预期的结果,后续读取token做校验时也会拿不到字符串格式的jwt,触发之前的报错。

修复方法

调整中间件的形参顺序即可,修正后的中间件代码如下:

const { verify } = require("jsonwebtoken")

const validateToken = (req, res, next) => {
    console.log(req.header('host'), 'req host')
    // 后续jwt校验逻辑可正常编写
    const accessToken = req.header("accessToken");
    if (!accessToken) return res.status(401).json({error: "未授权访问"});
    try {
        const userInfo = verify(accessToken, "你配置的jwt签名密钥");
        req.user = userInfo;
        next();
    } catch (err) {
        return res.status(403).json({error: "token校验失败"});
    }
}

module.exports = { validateToken }

补充说明

  • 你之前配置的CORS规则没有问题,修复参数顺序后自定义的accessToken请求头可以被正常读取
  • 修复后即可拿到字符串格式的token,不会再触发JsonWebTokenError: jwt must be a string报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:15:53