簡體   English   中英

NodeJS - https - 類型錯誤 [ERR_INVALID_HTTP_TOKEN]:Header 名稱必須是有效的 HTTP 令牌 [“接受”]

[英]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 模塊將對您在請求選項標頭中指定的每個鍵值對執行validateHeaderNamevalidateHeaderValue

所以如果你這樣做

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 ,您將收到相同的錯誤。


從節點 v10.20.1

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM