下面是一个带有 2 个 API 的网上商店服务器的精简部分:
./login
用于登录,./products
用于显示产品。产品只有在成功登录后才会显示。
我将 TypeScript 与 Node.js 和 Express 结合使用,并启用了会话管理。下面的代码还尝试通过向 API 发送
fetch()
请求来测试服务器。注意:所以我从 withinNode.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();
将此选项添加到您的
fetch()
通话中:
{ withCredentials: true }
否则,
fetch()
可能不会随请求发送 cookie。如果没有 cookie,就无法连接到现有会话,因此 Express 会创建一个新的空会话。
如果您是
fetch()
服务器端,那么您将需要某种 cookie jar 来收集并保留从一个请求到下一个请求的 cookie。