我的节点服务器正在生成一个json对象/数组。我需要将其发送给用户,但不要在浏览器上显示,而是作为文件显示。我该怎么做?
我不认为将它写入文件然后使用res.sendFile()
是正确的做法。
答案 0 :(得分:1)
您只需添加标题Content-Type
作为浏览器不会直接显示的内容,然后将内容作为附件下载。
如果您想为下载文件命名,那么您将不得不使用标题Content-Disposition
。
JSON对象可以简单地转换为字符串,并使用上面的两个标题发送。
以下是工作服务器代码。
http = require('http');
server = http.createServer( function(req, res) {
/**************** This is the important part **************/
res.writeHead(200, {
'Content-Type': 'application/json-my-attachment',
"content-disposition": "attachment; filename=\"my json file.json\""
});
var jsonObj = {"name":"Will McAvoy"};
res.end(JSON.stringify(jsonObj));
});
port = 3000;
host = '127.0.0.1';
server.listen(port, host);
console.log('Listening at http://' + host + ':' + port);
application/json-my-attachment
是一个由Content-Type
组成的名称,因为浏览器无法识别它,它会尝试下载它。否则,您还可以添加标准标题Content-Type: application/octet-stream
。
修改强>
关于第二个问题,如何在下载文件时在POST
请求中发送参数,可以使用HTML Form
轻松完成。
当您使用AngularJS
时,我假设您不希望通过提交表单来刷新页面。这可以使用IFrame
来完成。只需使用Javascript更新IFrame的src
属性即文件下载路径。
它解决了页面刷新问题,但我们无法仅使用IFrame发送POST
请求with body
。
我们必须使用combination of Form and IFrame
。 HTML表单有一个属性target
,我们可以在其中指定IFrame的名称。表单可以指定要使用的表单参数,操作和HTTP方法。由于目标是IFrame,因此无法刷新当前页面。
注意:此方法的限制是您无法使用表单提交发送HTTP标头,但有一些hacks available。
以下是工作代码。我使用Expressjs作为节点服务器。
<强> HTML 强>
<button id="downloadFile">download file</button>
<form id="downloadForm" method="post" action="http://localhost:3000/download" target="downloadIframe" style="display:none">
<input type="text" name="param1">
<input type="text" name="param2">
</form>
<iframe id="downloadIframe" name="downloadIframe" style="display:none"/>
<强>的Javascript 强>
$(function () {
$("#downloadFile").click(function () {
var form = $("#downloadForm");
form.find("[name=param1]").val("hello");
form.find("[name=param2]").val("world");
form.submit();
});
});
NPM安装
npm install express
npm install body-parser
节点服务器
var express = require('express');
var bodyParser = require('body-parser');
var path = require('path');
var fs = require('fs');
app = express(),
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
port = process.env.PORT || 3000;
app.all("/*", function (req, res) {
if(req.method = "POST" && req.url === "/download") {
/**************** This is the important part **************/
res.writeHead(200, {
'Content-Type': 'application/json-my-attachment',
"content-disposition": "attachment; filename=\"my json file.json\""
});
console.log("body : " + JSON.stringify(req.body));
var jsonObj = {"name":"Will McAvoy"};
res.end(JSON.stringify(jsonObj));
} else {
var filePath = req.url;
filePath = (filePath === "/") ? "index.html" : filePath;
filePath = path.join(__dirname, "public", filePath);
console.log(filePath);
fs.stat(filePath, function (err, stat) {
if(!err) {
res.sendFile(filePath);
} else {
res.writeHead(404);
res.end("file not found");
}
});
}
});
console.log("server started at : http://localhost:" + port);
app.listen(port);
**下载按钮上的服务器输出单击**
服务器起始于:http:// localhost:3000
body:{&#34; param1&#34;:&#34; hello&#34;,&#34; param2&#34;:&#34; world&#34;}