node通过http.request向其他服务器上传文件
发布于 13 年前 作者 seon 22303 次浏览 最后一次编辑是 8 年前

很早就听说过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>

2 回复

能说说服务器端是怎么接受的么

你搞这么多<br />干啥

回到顶部