[英]NodeJS - https - TypeError [ERR_INVALID_HTTP_TOKEN]: Header name must be a valid HTTP token ["Accept"]
我有一個使用https
模塊的 NodeJS 代碼: https.request(options, (res) => {......
其中options
是一個 object
const options = {
hostname: SERVICE_HOSTNAME,
path: BASE_PATH,
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
ApplicationId,
Authorization
}
};
當我添加Accept
header 時,我的問題就開始了。我收到一個錯誤:
TypeError [ERR_INVALID_HTTP_TOKEN]: Header name must be a valid HTTP token ["Accept"]
at ClientRequest.setHeader (_http_outgoing.js:472:3)
at new ClientRequest (_http_client.js:203:14)
at Object.request (https.js:289:10)
Accept
header怎么會失效呢?
現在這很瘋狂,但是您的“接受”字符串中有一個額外的字符。 如果你跑
console.log('Accept'.charCodeAt(6)) // prints 8203
(您必須使用問題中的“接受”副本運行它,我假設它是從其他地方復制粘貼的)
Unicode 8203 是零寬度空間,因此我們人類看不到它:)
順便說一句,最初我通過復制粘貼到節點 REPL 並在收到錯誤后注意到控制台 output 中的“正方形”來發現該字符。
然后,我嘗試將您的代碼復制粘貼到我的 IntelliJ 編輯器中,並驚喜地看到此警告:
hlfrmn 已經發現了這個棘手的錯誤並給出了正確的答案,以防萬一其他人感興趣:
從版本14.3.0開始,節點的 http 模塊將對您在請求選項標頭中指定的每個鍵值對執行validateHeaderName
和validateHeaderValue
。
所以如果你這樣做
const {validateHeaderName} = require('http');
try {
const options = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
}
};
for (const header in options.headers) {
validateHeaderName(header);
}
} catch (err) {
console.log(err);
}
將打印提到的錯誤:
TypeError [ERR_INVALID_HTTP_TOKEN]: Header name must be a valid HTTP token ["Accept"] will be printed from the catch block.
因為你的問題我沒吃T_T
正如@hlfrmn 所說,您的Accept 詞中有一個罕見的字符!
我重現了錯誤:
const https = require('https');
//copied from origin question
var copiedOptions = {
headers: {
'Content-Type': 'application/json',
"Accept": 'application/json'
}
}
var writedOptions = {
headers: {
'Content-Type': 'application/json',
"Accept": 'application/json'
}
}
https.get('https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY',writedOptions, (resp) => {
let data = '';
// A chunk of data has been recieved.
resp.on('data', (chunk) => {
data += chunk;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
console.log(JSON.parse(data).explanation);
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
如果您嘗試使用copyOptions ,您將收到相同的錯誤。
在https://github.com/nodejs/node/tree/master和 stackTrace 中搜索: _http_outgoing.js:472
at ClientRequest.setHeader (_http_outgoing.js:472:3)
我創立了這個:
const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/;
/**
* Verifies that the given val is a valid HTTP token
* per the rules defined in RFC 7230
* See https://tools.ietf.org/html/rfc7230#section-3.2.6
*/
function checkIsHttpToken(val) {
return tokenRegExp.test(val);
}
該正則表達式確保 header 名稱僅具有根據https://tools.ietf.org/html/rfc7230#section-3.2.6允許的標記或字符
也許 nodejs 核心中的早期驗證可能會有所幫助:
您的 header 名稱中有一個不允許的字符!
如果你有問題res.writeHead(200, {'Content-Type':'text/json'});
------> 您應該像這樣將單詞(文本)重命名為(應用程序)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.