我正在编写一段代码来为客户端加载页面。其中的一段代码是:
response.writeHead(301, {"Location": "/login/index.html"});
response.end("");问题是,如果我有一个名为A的慢速客户端,这段代码是否会阻止其他客户端的事件循环?或者它可以在A等待页面加载时处理其他事件?
我在一本书中读到,最好使用管道方法,就像下面的代码:
var fs = require('fs');
var rs = fs.createReadStream('/login/index.html');
rs.pipe(response);使用哪一个更好?
发布于 2013-05-20 19:14:33
正如@spotirca已经指出的,response.writeHead()不是缓存的,但我认为值得在这个问题的另一个方面展开讨论,即pipe()的使用。
pipe()在这里实际上是一个转移注意力的问题,问题是重定向是使用现有的HTTP响应还是开始一个新的周期。重要的是要理解这两种解决方案做的事情完全不同。
301重定向
response.writeHead(301, {"Location": "/login/index.html"});
response.end("");这使用永久重定向来响应浏览器,即告诉浏览器当前的应该总是重定向到指定的URL。如果您根据用户的会话状态将用户重定向到登录页面,那么这绝对是错误的,因为浏览器有理由缓存重定向并导致不受欢迎的行为。
流式传输
require('fs').createReadStream('/login/index.html').pipe(response);这是可行的,但这意味着无论当前URL是什么,登录页面都将被提供。你也会打破标准的HTTP行为,在同一个URL上提供不同的内容,所以@spotirca指出,这会对缓存产生影响。
我的建议
使用302 (临时)重定向到/login/,然后从那里提供内容。
response.writeHead(302, {"Location": "/login/"});
response.end("");我从不在URL中包含文件扩展名,因为这会降低您以后更改内容的能力,但这种方法的这一方面意味着您需要有一个请求处理程序来侦听该URL并提供静态文件。为此,您可以使用pipe()并设置合适的缓存头,但我的建议是使用Express或类似的框架来避免与自定义代码相关的but。
例如:
// A framework will do most of this for you
response.writeHead("Expires","Thu, 01 Dec 2994 16:00:00 GMT");
require('fs').createReadStream('/login/index.html').pipe(response);发布于 2013-05-21 02:39:04
不,writeHead不占用I/O。它不从网络/磁盘读取或写入。它只是写入response (http.ServerResponse对象),该对象驻留在内存中。您创建/发送的每个响应都是一个单独的对象。每个响应只能调用一次,这样writeHead就不会阻塞。http.ServerResponse实现了一个用于同步的Writable Stream接口。
为了回答你的问题,它不能阻止客户端加载页面,不像SQL查询需要排序/序列化,writeHead需要简单的同步。
您已经读取的管道()方法当然更好,但只是在同步文件读取和较少文件读取方面。如果执行同步的readFileSync,将强制磁盘读取,并将阻塞节点服务器的其余部分的执行。所以如果你使用它,你就不能在读取文件时执行任何事情(做一些有意义的事情)。
但是要说你确实在用它。然后,对于每个请求,将从磁盘异步读取文件,但如果文件没有更改,则不需要这样做。将其读取到内存中一次,然后将其用于进一步的请求是明智的。对于静态文件,最好使用只在磁盘上发生更改时才执行读操作的缓存。
因此,最好使用像express那样的静态文件服务器。参见this。
发布于 2013-05-20 15:30:54
不,writeHead不是同步的,它不会阻塞事件循环。我不建议在这个特定的例子中使用管道。我有两个原因:
/login/index.html,是一个静态文件,可以缓存,因此降低了网络传输。非常有用,特别是对于速度较慢的客户端connections.https://stackoverflow.com/questions/16644398
复制相似问题