Node.js 给出不同超时的不同 HTTP 响应
Node.js is giving different HTTP responses with different timeouts
我正在使用 Node.js
作为后端(我只是用 localhost
测试它),我注意到这段代码...
response.writeHead(200, { 'Content-Type': 'text/html' });
fs.readFile('index.html', (_err, data) => {
response.end(data);
});
response.writeHead(200, {'Content-Type': 'application/json'})
const responseBody = { headers, method, url, body };
response.write(JSON.stringify(responseBody));
response.end();
...第二个 response.end()
调用“覆盖”了第一个(html
页面从未显示)。
所以我决定使用 setTimeout
看看我是否可以先显示 index.html
的内容,然后在几秒钟后显示 application/json
响应...
setTimeout(() => {
response.writeHead(200, {'Content-Type': 'application/json'})
const responseBody = { headers, method, url, body };
response.write(JSON.stringify(responseBody));
response.end();
}, 1000);
...但是在第一个 response.end()
调用后,我再也看不到 json
出现了。
然后我有了一个奇怪的想法,我决定把超时时间从1000ms
改成1ms
,然后html
的内容就再也不显示了,我马上(或者可能在1ms
,就是这么少的时间)看到了json
的内容。
我尝试使用 10ms
,但它与 1000ms
一样有效,然后我尝试使用 2ms
,刷新页面有时显示 json
,有时显示 html
.
这怎么可能? response.end()
函数不会等到 response
结束?是不是其他原因引起的?提前谢谢你。
当您使用 setTimeout 时,超时的代码会被推送到执行堆栈的“末尾”,然后恢复正常的程序执行。
在这种情况下,发送响应以及如果您直接删除那里的代码将会发生的一切。
我认为您说的 response.end()
不会等到文件传输实际结束。
我实际上在使用 express 时了解到:
如果您在同一函数中执行 response.sendFile(...)
后跟 response.end()
,则不会发送实际文件(在实际发送文件之前响应为 'closed'),它只会给出空响应.
编辑:
在您的第一个代码中,JSON 写入总是比 readFile
回调执行得早。 (readFile 回调具有 asynchronous
行为。)
但是一旦超时,“超时回调”和“readFile 回调”之间就会发生竞争。
由于文件加载时间可能会有所不同,因此有时可能比超时时间更快,有时更慢。但是无论哪个回调'wins the race',它都会调用response.end()
,阻止另一个回调发送任何东西。
我正在使用 Node.js
作为后端(我只是用 localhost
测试它),我注意到这段代码...
response.writeHead(200, { 'Content-Type': 'text/html' });
fs.readFile('index.html', (_err, data) => {
response.end(data);
});
response.writeHead(200, {'Content-Type': 'application/json'})
const responseBody = { headers, method, url, body };
response.write(JSON.stringify(responseBody));
response.end();
...第二个 response.end()
调用“覆盖”了第一个(html
页面从未显示)。
所以我决定使用 setTimeout
看看我是否可以先显示 index.html
的内容,然后在几秒钟后显示 application/json
响应...
setTimeout(() => {
response.writeHead(200, {'Content-Type': 'application/json'})
const responseBody = { headers, method, url, body };
response.write(JSON.stringify(responseBody));
response.end();
}, 1000);
...但是在第一个 response.end()
调用后,我再也看不到 json
出现了。
然后我有了一个奇怪的想法,我决定把超时时间从1000ms
改成1ms
,然后html
的内容就再也不显示了,我马上(或者可能在1ms
,就是这么少的时间)看到了json
的内容。
我尝试使用 10ms
,但它与 1000ms
一样有效,然后我尝试使用 2ms
,刷新页面有时显示 json
,有时显示 html
.
这怎么可能? response.end()
函数不会等到 response
结束?是不是其他原因引起的?提前谢谢你。
当您使用 setTimeout 时,超时的代码会被推送到执行堆栈的“末尾”,然后恢复正常的程序执行。
在这种情况下,发送响应以及如果您直接删除那里的代码将会发生的一切。
我认为您说的 response.end()
不会等到文件传输实际结束。
我实际上在使用 express 时了解到:
如果您在同一函数中执行 response.sendFile(...)
后跟 response.end()
,则不会发送实际文件(在实际发送文件之前响应为 'closed'),它只会给出空响应.
编辑:
在您的第一个代码中,JSON 写入总是比 readFile
回调执行得早。 (readFile 回调具有 asynchronous
行为。)
但是一旦超时,“超时回调”和“readFile 回调”之间就会发生竞争。
由于文件加载时间可能会有所不同,因此有时可能比超时时间更快,有时更慢。但是无论哪个回调'wins the race',它都会调用response.end()
,阻止另一个回调发送任何东西。