同浏览器访问 express 的相同 route 会被阻塞是为什么?
发布于 2年前 作者 wyatt 1432 次浏览

问题是这样的, 本来是想做一个提供抓取服务的 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

回到顶部