Home > Web Front-end > JS Tutorial > body text

Node.js implements file upload

高洛峰
Release: 2016-12-24 17:23:20
Original
1524 people have browsed it

I encountered such a demand at work. I needed to use nodejs to upload files. Before, I only knew how to upload files through a browser. Using nodejs is equivalent to simulating the behavior of a browser. After some google searching, I realized that the browser just uses the http protocol to transmit data to the server. The specific protocol is "RFC 1867 - Form-based File Upload in HTML". This is how to upload files through the form form on the browser. protocol, we can first see what data the browser sends to the server, and then we can implement the upload function in the same way. Speaking of form uploading files, everyone should be familiar with it:

<form action="http://www.qq.com/" method="post">
<input type="text" name="text1" /><br />
<input type="text" name="text2" /><br />
<input type="submit" />
</form>
Copy after login


When submitting, you can use fiddler to capture the packet and you can see that such data is sent to the server:

POST http://www.qq .com/ HTTP/1.1
Host: www.qq.com
Content-Length: 23
Content-Type: application/x-www-form-urlencoded; charset=UTF-8

text1=hello&text2=world

Worth it Note that Content-Type defaults to application/x-www-form-urlencoded, so the message will be URL encoded. For example, "Hello" would be encoded as %E4%BD%A0%E5%A5%BD.

Next let’s take a look at how to upload through the form. Everyone should be familiar with it:

<form action="http://www.qq.com" method="post" enctype="multipart/form-data">
<input type="file" name="myfile" />
<input type="submit" value="submit" />
</form>
Copy after login


Then create a new upload.txt text file with only the words "hello world" and upload it. We then use fiddler to capture the package. We can find that the data sent is a little more complicated. (A lot of other irrelevant request lines have been removed, such as cache control and cookies):

POST http://www.qq.com/ HTTP/1.1
Host: www.qq.com
Content- Length: 199
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarywr3X7sXBYQQ4ZF5G

------WebKitFormBoundarywr3X7sXBYQQ4ZF5G
Content-Disposition: form-data; name="myfile"; filename="upload. txt"
Content-Type: text/plain

hello world

------WebKitFormBoundarywr3X7sXBYQQ4ZF5G--

According to the definition of RFC 1867, we need to generate a piece of boundary data. This data cannot appear elsewhere in the content. This can be defined by yourself. The generation algorithm of each browser may be different. The above boundary is to separate the data. After the separated data is generated, the separated data can be placed in the Content-Type of the header and sent to the server. That is the above Content-Type: multipart/form-data; boundary=----WebKitFormBoundarywr3X7sXBYQQ4ZF5G. In addition, the uploaded content needs to be separated into several segments using delimited data, and then each segment of data contains files. name, and the name when uploading. The server uses this name to receive the file, and the file type Content-Type. In this example, it is text/plain. If the uploaded png image is image/png. A blank line after the file type is the content of the uploaded file. In this example, for the sake of ease of understanding, a text file is uploaded, so the content can be displayed directly. If an image file is uploaded, because it is a binary file, fiddler It just shows garbled characters. After the content of the file ends, there is a blank line plus boundary data.

After understanding the details of the sending format, the next step is to use nodejs to program. Simply put, it is just to send the data to the server according to the format.

const http = require(&#39;http&#39;);
const fs = require(&#39;fs&#39;);
//post地址为本地服务的一个php,用于测试上传是否成功
var options = {
hostname: &#39;localhost&#39;,
port: 80,
path: &#39;/get.php&#39;,
method: &#39;POST&#39;
}
//生成分隔数据
var boundaryKey = &#39;----WebKitFormBoundaryjLVkbqXtIi0YGpaB&#39;;
//读取需要上传的文件内容
fs.readFile(&#39;./upload.txt&#39;, function (err, data) {
//拼装分隔数据段
var payload = &#39;--&#39; + boundaryKey + &#39;\r\n&#39; + &#39;Content-Disposition:form-data; name="myfile"; filename="upload.txt"\r\n&#39; + &#39;Content-Type:text/plain\r\n\r\n&#39;;
payload += data;
payload += &#39;\r\n--&#39; + boundaryKey + &#39;--&#39;;
//发送请求
var req = http.request(options, function (res) {
res.setEncoding(&#39;utf8&#39;);
res.on(&#39;data&#39;, function (chunk) {
console.log(&#39;body:&#39; + chunk);
});
});
req.on(&#39;error&#39;, function(e) {
console.error("error:"+e);
});
//把boundary、要发送的数据大小以及数据本身写进请求
req.setHeader(&#39;Content-Type&#39;, &#39;multipart/form-data; boundary=&#39;+boundaryKey+&#39;&#39;);
req.setHeader(&#39;Content-Length&#39;, Buffer.byteLength(payload, &#39;utf8&#39;));
req.write(payload);
req.end();
});
Copy after login


The focus of this article is to understand the protocol and implement it with code. There are many areas for optimization in code organization.

Finally, in the local apache, simply write a php to save the uploaded file for testing:

<?php
$filePath = &#39;./upload.txt&#39;;
move_uploaded_file($_FILES[&#39;myfile&#39;][&#39;tmp_name&#39;] , $filePath);
echo "ok";
?>
Copy after login


In addition, according to RFC 1867, the function of uploading multiple files at one time can also be implemented. This is here Without going into details, you can refer to RFC 1867 for details if necessary.

The above is the Node.js implementation of file upload introduced by the editor. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. I would also like to thank you all for your support of the PHP Chinese website!


For more articles related to Node.js implementation of file upload, please pay attention to the PHP Chinese website!


Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!