Nodejs 通过http.request向其他服务器上传文件
Nodejs 通过http.request向其他服务器上传文件
很早就听说过node的大名了,只是一直没有去尝试。直到最近,为了简化代码上线流程,提高上线效率,决定使用node来开发服务器端的上线程序。 <br/> <br/>服务器主要完成在svn服务器上创建tag,代码的合并、压缩与打包,压缩包提交至CMS服务器,经由CMS服务器发布至全网cdn等一系列的流程。 <br/> <br/>开始的一系列开发工作都比较顺利,但是,当做到将压缩包上传至CMS服务器时,遇到了困难。我不知道该如何通过node发起一条带有文件的post请求。。。 <br/> <br/>通过查阅node的api手册,发现node是支持在服务器端发起http请求的。那么,剩下的麻烦的问题,就是,该如何构造该请求。 <br/> <br/>之前虽然也写过一段时间的后端代码,但是都是通过封装好的接口来实现的,但对于node来说,没有现成的实现。无奈,只好向google求助。 <br/> <br/>很快搜到了一篇帖子,介绍相关内容的,并且还附赠了代码!不过可惜的是,所附的代码还是存在问题,估计作者并没有亲测过。但这篇帖子却着实的让我受到了很大的启发,至少让我清楚了两件事情:1、上传文件的http请求的body部分的格式;2、文件转化为http数据流的方式! <br/> <br/>基于以上两点,我慢慢摸索出了上传文件的方法,在这里跟大家分享以下! <br/> <br/>先简单的描述下http协议分包传输时的数据格式。 <br/> <br/><strong>Content-type</strong> <br/> <br/>Content-type需要指定为 <br/><pre>multipart/form-data; boundary=’ + boundaryKey</pre> <br/>其中boundaryKey为一随机字符串,用于标识请求数据段。 <br/> <br/><strong>请求体格式</strong> <br/> <br/>每一段请求体均以"–" + boundaryKey开头,然后使用’\r\n’来做行分隔。 <br/> <br/>接下来是每一段请求体的描述信息,包括Content-Type以及<pre><code>Content-Disposition</pre></code>等字段信息。每一个字段信息结尾都以’\r\n’来标识行结束。 <br/> <br/>描述信息与请求体正文需要以一个空行隔开,即需要再输出一个’\r\n’。 <br/> <br/>最后是请求提正文。 <br/> <br/>直到最后一个请求体结束之后,再输出’\r\n–’ + boundaryKey + ‘–‘作为整个请求的结束。 <br/> <br/>这样即完成了一次post请求所需的基本内容了。 <br/> <br/>接下来,在介绍下,将文件转换为http数据流所需要做的工作。 <br/> <br/>转换的基本过程: <br/><ol> <br/> <li>调用http.request方法,返回一个<pre><code>http.ClientRequest类的实例</pre></code>。<pre><code>http.ClientRequest的实例本质上来说是一个</pre></code>writable stream。</li> <br/> <li>对要上传的文件创建一个读取文件流。</li> <br/> <li>将从文件读取到的流数据写到http请求数据流中。</li> <br/> <li>关闭http请求。</li> <br/></ol> <br/>所需要用到的接口: <br/><ol> <br/> <li>http.request</li> <br/> <li>createReadStream</li> <br/> <li>stream.pipe</li> <br/> <li>stream.on(‘end’)事件</li> <br/></ol> <br/>综合以上内容,给出简单实现的代码,供大家参考,欢迎大家交流! <br/><pre>function upload(){ <br/> var boundaryKey = ‘----’ + new Date().getTime(); <br/> var options = { <br/> host:‘www.test.com’,//远端服务器域名 <br/> port:80,//远端服务器端口号 <br/> method:‘POST’, <br/> path:’/upload’,//上传服务路径 <br/> headers:{ <br/> ‘Content-Type’:‘multipart/form-data; boundary=’ + boundaryKey, <br/> ‘Connection’:‘keep-alive’ <br/> } <br/> }; <br/> var req = http.request(options,function(res){ <br/> res.setEncoding(‘utf8’); <br/> res.on(‘data’, function (chunk) { <br/> console.log(‘body: ’ + chunk); <br/> }); <br/> res.on(‘end’,function(){ <br/> console.log(‘res end.’); <br/> }); <br/> }); <br/> req.write( <br/> ‘–’ + boundaryKey + ‘\r\n’ + <br/> ‘Content-Disposition: form-data; name=“upload”; filename=“test.zip”\r\n’ + <br/> ‘Content-Type: application/x-zip-compressed\r\n\r\n’ <br/> ); <br/> //设置1M的缓冲区 <br/> var fileStream = fs.createReadStream(’/data/test.zip’,{bufferSize:1024 * 1024}); <br/> fileStream.pipe(req,{end:false}); <br/> fileStream.on(‘end’,function(){ <br/> req.end(’\r\n–’ + boundaryKey + ‘–’); <br/> }); <br/>}</pre>
能说说服务器端是怎么接受的么
你搞这么多<br />干啥
在Node.js中,可以通过http.request
方法来向其他服务器上传文件。下面是一个具体的示例代码,展示了如何通过http.request
上传文件:
const http = require('http');
const fs = require('fs');
function uploadFile() {
const boundaryKey = '----WebKitFormBoundary7MA4YWxkTrZu0gW';
const options = {
hostname: 'www.test.com',
port: 80,
method: 'POST',
path: '/upload',
headers: {
'Content-Type': `multipart/form-data; boundary=${boundaryKey}`,
'Connection': 'keep-alive'
}
};
const req = http.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Response received:', data);
});
});
req.write(`--${boundaryKey}\r\n`);
req.write('Content-Disposition: form-data; name="file"; filename="test.zip"\r\n');
req.write('Content-Type: application/octet-stream\r\n\r\n');
const fileStream = fs.createReadStream('/data/test.zip');
fileStream.pipe(req);
fileStream.on('end', () => {
req.write(`\r\n--${boundaryKey}--\r\n`);
req.end();
});
}
uploadFile();
代码解释
-
初始化HTTP请求:
- 使用
http.request
方法创建一个HTTP请求对象。 - 设置请求的
hostname
,port
,method
,path
和headers
。
- 使用
-
写入请求头:
- 在请求体中写入多部分表单数据的边界字符串和文件相关信息。
-
读取文件并发送:
- 使用
fs.createReadStream
创建文件读取流。 - 将文件读取流通过
pipe
方法写入HTTP请求对象。
- 使用
-
结束请求:
- 当文件读取完成后,写入结束标记符并结束请求。
这段代码展示了如何使用Node.js的http.request
方法上传文件到远程服务器。希望这对你有所帮助!