同浏览器访问 express 的相同 route 会被阻塞是为什么?
发布于 12 年前 作者 wyatt 5538 次浏览 最后一次编辑是 8 年前

问题是这样的, 本来是想做一个提供抓取服务的 API 项目, 使用的是 express. 在测试的过程中, 测试一下异步抓取的效果, 结果在同一个浏览器的多个 Tab 访问同一个 route 会被阻塞住, 然后在 stackoverflow 中找到这篇一样的问题, 最后一句话 “I got the reason, it is because I ran two ‘/a’ on the same browser. I just tried to run one in chromium, and the other one in firefox, they were handled asyncly. Looks interesting.” 然后我在本地用 ruby 脚本写了个多线程访问测试了一下, 又能够异步并不阻塞(用不同的浏览器也可以).

Node.js 入门 中也有一个编写非阻塞的例子, 其使用的是 node.js 的 http 库, 并没有像 express 那样同浏览器访问会阻塞的情况, 所以我猜想应该是 express 在处理请求的时候做了某些处理(猜测在 Cookie 上), 让同浏览器的访问进行了阻塞. 因为刚刚接触 express 不久, 又想弄清楚是怎么一回事, 是否有人知道是 express 做了什么处理或者是什么地方的影响?

3 回复

你的express页面执行时间是多少呢?

尝试关闭多个TAB测试,而在单一页面上用F5刷新测试,响应时间是否与单次访问的时间差不多? 如果是,那就是浏览器的原因,如果不是,要阻塞页面只能是这个抓取是同步操作,或者你队列了它。express处理URL只是调用一系列函数,不可能做这种阻塞的

老外也说了,换成2个浏览器就正常,证明服务端是没问题的,问题出在浏览器

你这么一说, 我拿 Chrome 与 Safari 做了下测试, 每个浏览器同时打开两个 Tab 访问 localhost:3000/a :

express = require 'express'
app = express()
app.use(express.logger('dev'))

app.get '/a', (req, res, next) ->
  f = ->
    res.send 'a' 
    console.log 'end', new Date()
  console.log 'sleep', new Date()
  setTimeout f, 10000

app.get '/b', (req, res, next) ->
  res.send 'b'

Safari 输出

GET /a 200 10001ms - 1
end Mon Dec 17 2012 13:27:15 GMT+0800 (PHT)
sleep Mon Dec 17 2012 13:27:15 GMT+0800 (PHT)
GET /a 200 10000ms - 1
end Mon Dec 17 2012 13:27:16 GMT+0800 (PHT)
sleep Mon Dec 17 2012 13:27:16 GMT+0800 (PHT)

Chrome 输出

GET /a 200 10003ms - 1
end Mon Dec 17 2012 13:29:39 GMT+0800 (PHT)
sleep Mon Dec 17 2012 13:29:39 GMT+0800 (PHT)
GET /favicon.ico 404 1ms
GET /a 200 10001ms - 1
end Mon Dec 17 2012 13:29:49 GMT+0800 (PHT)
sleep Mon Dec 17 2012 13:29:49 GMT+0800 (PHT)
GET /favicon.ico 404 1ms

这样看来, 是 Chrome 对没有返回的请求阻塞了下一个相同请求, express 没有做处理. 很意外… 很意外…

补充一个链接. Chrome 与 Firefox 都会对相同请求的 URL 进行串行化. http://www.laruence.com/2011/07/16/2123.html

回到顶部