我能夠使用 Firefox 成功登錄網站,但無法使用 node-fetch 復制該登錄。登錄程序分為三個階段:
- 轉到 /login 和網站回應 sessionToken (這部分作業正常)
- 在 sessionToken 旁邊輸入電子郵件和密碼,網站用 sessionToken 和 authToken 回應(這是我遇到問題的部分)
- 使用 sessionToken 和 authToken 向 /portal 發出請求,網站回應我嘗試訪問的 HTML
在 Firefox Dev Tools 中,我可以看到作業標頭和作業請求正文。當我在開發工具中單擊“請求”時,我看到一個“表單資料”標題,其中包含正確的“電子郵件”和“密碼”值。當我在開發工具中單擊“標題”時,這是成功的 Firefox 請求:
POST /login/action HTTP/2
Host: www.website.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0
Accept: text/html,application/xhtml xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 46
Origin: https://www.website.com
Connection: keep-alive
Referer: https://www.website.com/login
Cookie: _sessiontoken=sessionTokenHere
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
TE: trailers
在 Firefox 上,它會回傳帶有以下標頭的 302(重定向)回應:
HTTP/2 302 Found
date: Sun, 31 Oct 2021 17:25:03 GMT
content-type: text/html; charset=utf-8
cache-control: no-cache
location: https://www.website.com/portal
x-runtime: 9
set-cookie: auth_token=authtokenHere; path=/
set-cookie:
set-cookie: _sessiontoken=sessionTokenHere; path=/; HttpOnly
cf-cache-status: DYNAMIC
[omitted for brevity: expect-ct, report-to, nel, server, cf-ray, alt-svc, X-Firefox-Spdy]
現在,這是我嘗試在 node.js 中與 node-fetch 一起使用的 POST 選項:
{
method: 'POST', headers: {
Host: 'www.website.com'
,'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0'
,Accept: 'text/html,application/xhtml xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
'Accept-Language': 'en-US,en;q=0.5',
'Accept-Encoding': 'gzip, deflate, br',
'Content-Length': 46,
Origin: 'https://www.website.com',
Connection: 'keep-alive',
Referer: 'https://www.website.com/login',
Cookie: '_sessiontoken=sessionTokenHere'
'Upgrade-Insecure-Requests': '1',
'Sec-Fetch-Dest': 'document',
'Sec-Fetch-Mode': 'navigate',
'Sec-Fetch-Site': 'same-origin',
'Sec-Fetch-User': '?1',
TE: 'trailers',
body: URLSearchParams { 'email' => 'myEmail','password' => 'myPassword'}
但是,當使用帶有上述選項的 node-fetch 時,它回傳 200,而不是 302。以下是該回應的標頭(通過 fetch() 函式中的 console.log() 列印):
[Object: null prototype] {
date: [ 'Sun, 31 Oct 2021 18:12:01 GMT' ],
'content-type': [ 'text/html; charset=utf-8' ],
'transfer-encoding': [ 'chunked' ],
connection: [ 'keep-alive' ],
vary: [ 'Accept-Encoding' ],
'x-runtime': [ '5' ],
'cache-control': [ 'private, max-age=0, must-revalidate' ],
'set-cookie': [
'_sessionToken=sessionTokenHere; path=/; HttpOnly'
],
'cf-cache-status': [ 'DYNAMIC' ],
'content-encoding': [ 'br' ],
[omitted for brevity: expect-ct, report-to, nel, server, cf-ray, alt-svc]
}
我很困惑為什么它在 Firefox 中有效,但在 node-fetch 中無效。一些注意事項:
- 我懷疑我以某種方式錯誤地包含了電子郵件和密碼,但我不知道如何
- 正在作業的 Firefox 請求在回應標頭中包含“X-Firefox-Spdy”;非作業節點獲取請求沒有。
- 根據這篇文章的建議,我沒有在我的請求中包含“內容型別”
- Firefox 請求似乎使用 HTTP/2。這可能是問題的一部分嗎?
uj5u.com熱心網友回復:
node-fetch自動跟隨重定向。它將自動轉到下一個重定向的 url(Locationhttp 標頭值)。
如果你想趕上301或302電話,您可以設定redirect屬性manual中的選項一樣redirect: "manual",這樣你管理自己的重定向
例如,以下代碼將捕獲301呼叫(302理論上它會為您做同樣的事情,在此處實作):
const fetch = require("node-fetch");
(async () => {
const response = await fetch("https://stackoverflow.com/users/2614364", {
redirect: "manual",
});
console.log(response.status);
console.log(response.headers.get("set-cookie"));
})();
我想你想使用 response.headers.get("set-cookie")
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/351505.html
標籤:javascript html http 网页抓取 fetch
下一篇:嵌入式Linux開發工具
