提前谢谢。
短:
由于请求中的Accept头,ExpresJS4.0会更改输出数据。是否有一种方法可以覆盖此行为,而不考虑请求头,只需编写相同的数据。
当Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8出现时,输出将被更改。
有什么办法我可以忽略,删除,覆盖这些头。
龙(可能是博士):
我正在尝试从Node/ExpressJS应用程序中提供二进制数据。我正在存储一个压缩的日志文件(纯文本),它已经被gzipped压缩,base64编码并发送到我的服务器应用程序,在那里它被存储在一个使用mongoose的mongo数据库中。我知道这可能不是最理想的,但目前是一个必要的邪恶。这很好用。
$(gzip --stdout /var/log/cloud-init-script.log | base64 --wrap=0)用于压缩和base64数据,然后将其与其他数据一起作为json post的一部分发送。
当我试图检索、解码base64编码的字符串并将其作为二进制gzip文件发送到浏览器时,就会出现问题。
// node, referring to the machine the log came from
var log = new Buffer(node.log, 'base64');
res.setHeader('Content-Disposition', 'attachment; filename=' + node.name + "-log.gz");
res.setHeader('Content-Type', 'application/x-gzip');
res.setHeader('Content-Length', log.length);
console.log(log.toString('hex'));
// res.end(log, 'binary'); I tried this hoping I could by pass, some content-negotiation
res.send(log);在使用ExpressJS 3.0使用res.send时,我已经完成了这个任务。但是当我更新到ExpressJS 4.0下载的数据时,就停止了正确的提取。被删除的数据似乎在某种程度上腐败。
我开始尝试通过使用xxd或od比较已下载文件和十六进制输出中的源文件来修复这个问题,并发现下载的文件与源代码不同。在将NodeJS缓冲区发送到控制台之前,我还转储了它的十六进制,这与源匹配。
我已经对此进行了近一天的讨论,并怀疑NodeJS在字符编码(UTF-8 v. Buffer v. UTF16 Strings)中做了一些古怪的事情。
最终发现这一切都不是问题,我以为NodeJS总是把错误的数据输出到浏览器中,这是正确的,但并不是“总是”输出错误的数据。
我有一个突破,当我向端点发出一个curl请求时,数据如预期的那样通过(与源匹配),然后我添加了与我的浏览器请求一起发送的请求头,并返回了损坏的数据。
实际日志文件:
I'm a log file良好要求:
> User-Agent: curl/7.37.1
> Host: 127.0.0.1:9000
> Accept: */*
>
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Last-Modified: Tue, 26 May 2015 11:47:46 GMT
< Content-Description: File Transfer
< Content-Disposition: attachment; filename=test-log.gz
< Content-Type: application/x-gzip
< Content-Transfer-Encoding: binary
< Content-Length: 57
< Date: Tue, 26 May 2015 11:47:46 GMT
< Connection: keep-alive
0000000: 1f8b 0808 0256 6455 0003 636c 6f75 642d .....VdU..cloud-
0000010: 696e 6974 2d73 6372 6970 742e 6c6f 6700 init-script.log.
0000020: f354 cf55 4854 c8c9 4f57 48cb cc49 e502 .T.UHT..OWH..I..
0000030: 003b 5ff5 5f0f 0000 00 .;_._....要求不佳:
> Host: localhost:9000
> Connection: keep-alive
> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.65 Safari/537.36
> Referer: http://localhost:9000/nodes?query=environment%3D5549b6cbdc023b5e26fe6bd4%20type%3Dnat
> Accept-Language: en-US,en;q=0.8
>
< HTTP/1.1 200 OK
< X-Powered-By: Express
< Last-Modified: Tue, 26 May 2015 11:47:00 GMT
< Content-Description: File Transfer
< Content-Disposition: attachment; filename=test-log.gz
< Content-Type: application/x-gzip
< Content-Transfer-Encoding: binary
< content-length: 57
< Date: Tue, 26 May 2015 11:47:00 GMT
< Connection: keep-alive
0000000: 1ffd 0808 0256 6455 0003 636c 6f75 642d .....VdU..cloud-
0000010: 696e 6974 2d73 6372 6970 742e 6c6f 6700 init-script.log.
0000020: fd54 fd55 4854 fdfd 4f57 48fd fd49 fd02 .T.UHT..OWH..I..
0000030: 003b 5ffd 5f0f 0000 00 .;_._....发布于 2015-05-28 05:36:17
res.end(node.log, 'base64');而不是
res.send(log);其中node.log是原始的base64编码字符串,日志是解码该字符串的缓冲区。
请记住,我使用的是Node v0.10.38。
最后,我跟踪了函数调用链。
// I call
res.send(log);
// ExpressJS calls on http.ServerResponse
this.end(chunk, encoding); // chunk = Buffer, encoding = undefined
// NodeJS http.ServerResponse calls
res.inject(string);此时,NodeJS似乎将数据视为字符串,这是缓冲区内容被破坏的地方。
当'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'头不存在时,这种行为是不同的,在本例中调用的是不同的end(chunk, encoding)函数,不使用res.inject,也不损坏缓冲区数据。
我不太清楚内容协商在哪里进行,以及在不同的res.end函数中交换了什么,这是NodeJS还是ExpressJS,但是能够以某种简单的方式控制这个内容协商是很好的。
https://stackoverflow.com/questions/30458015
复制相似问题