来自 Node.js 的 Fetch() 调用总是创建新的 Express 会话

问题描述 投票:0回答:1

下面是一个带有 2 个 API 的网上商店服务器的精简部分:

./login
用于登录,
./products
用于显示产品。产品只有在成功登录后才会显示。

我将 TypeScript 与 Node.js 和 Express 结合使用,并启用了会话管理。下面的代码还尝试通过向 API 发送

fetch()
请求来测试服务器。注意:所以我从
within
Node.js 发送 fetch() 请求,而不是从浏览器发送。下面的代码产生以下输出:

Login session ID: um2RykooJCer7Oy7YmJQs7s9ge3mZWL1
Products session ID: uAk03ochUM56rzJjPvbiRnFuPG8CUqTB
Products response: Error: Not logged in

可以看到session ID不一样,所以无法展示产品。当我让代码运行并在浏览器中手动输入 API 调用时:

http://localhost:3000/login
http://localhost:3000/products

然后代码可以正常工作,浏览器显示“Login OK”,然后显示“Apple、Orange、Pear”,两者都具有相同的会话 ID。

所以问题是:如何使服务器测试能够与 Node.js 中的

fetch()
正常工作,就像从浏览器调用时一样?是否可以为
fetch()
请求或 Express 提供一些选项?我还没找到。

额外问题:它也可以与 npm 包 node-fetch 一起使用吗?我使用它是因为 Node.js 中的内置

fetch()
在其他地方给出了错误。

PS 我正在使用最新版本的 Node.js (v21.5)、Express、express-session 和 node-fetch。

import Express from "express";
import Session from "express-session";
// Uncomment this to use the node-fetch module, but gives the same result:
// import fetch from "node-fetch";

declare module 'express-session' {
    interface SessionData
    {
        loggedIn: boolean;
    }
}

class App
{
    express = Express();

    start()
    {
        let session = Session( { secret: "my-secret", /* options? */ } );
        this.express.use( session );
        this.express.get( "/login", ( request, response ) => this.onLoginRequest( request, response ) );
        this.express.get( "/products", ( request, response ) => this.onProductsRequest( request, response ) );
        this.express.listen( 3000, () => this.requestLogin() );
    }

    // =================================== Login

    requestLogin()
    {
        fetch( 'http://localhost:3000/login', { /* options? */ } )
            .then( result => this.showProducts() );
    }

    onLoginRequest( request: Express.Request, response: Express.Response )
    {
        console.log( "Login session ID: " + request.session.id );
        request.session.loggedIn = true;
        response.send( "Login OK" );
    }

    // =================================== Products

    showProducts()
    {
        fetch( 'http://localhost:3000/products', { /* options? */ } )
            .then( result => this.onProducts( result ) );
    }

    onProductsRequest( request: Express.Request, response: Express.Response )
    {
        console.log( "Products session ID: " + request.session.id );
        if( !request.session.loggedIn )
            response.send( "Error: Not logged in" );
        else
            response.send( "Apple, Orange, Pear" );
    }

    onProducts( result: any )
    {
        result.text()
            .then( ( text: string ) => console.log( "Products response: " + text ) );
    }
}

( new App() ).start();
javascript node.js express session fetch
1个回答
0
投票

将此选项添加到您的

fetch()
通话中:

{ withCredentials: true }

否则,

fetch()
可能不会随请求发送 cookie。如果没有 cookie,就无法连接到现有会话,因此 Express 会创建一个新的空会话。

如果您是

fetch()
服务器端,那么您将需要某种 cookie jar 来收集并保留从一个请求到下一个请求的 cookie。

© www.soinside.com 2019 - 2024. All rights reserved.