在工作中碰到了這樣的需求,需要用nodejs 來上傳文件,之前也只是知道怎麼透過瀏覽器來上傳文件, 用nodejs的話, 相當於模擬瀏覽器的行為。 google 了一番之後, 明白了瀏覽器無非就是利用http協議來給伺服器傳輸數據, 具體協議就是《RFC 1867 - Form-based File Upload in HTML》, 在瀏覽器上透過form 表單來上傳文件就是透過這個協議,我們可以先看看瀏覽器給服務端發送了什麼數據, 就可以依葫蘆畫瓢的把上傳功能實現出來。說起form 表單上傳檔案的話, 大家應該很熟悉:
<form action="http://www.qq.com/" method="post"> <input type="text" name="text1" /><br /> <input type="text" name="text2" /><br /> <input type="submit" /> </form>
提交時, 用fiddler 抓包可以看到向服務端發出這樣的資料:
.com/ HTTP/1.1
Content-Length: 23
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
text1=hello&text2=world值得注意的是Content-Type預設為application/x-www-form-urlencoded,所以訊息會經過URL編碼。例如「你好」會編碼為 %E4%BD%A0%E5%A5%BD。
<form action="http://www.qq.com" method="post" enctype="multipart/form-data"> <input type="file" name="myfile" /> <input type="submit" value="submit" /> </form>
Host: www.qq.com
Content- Length: 199
------WebKitFormBoundarywr3X7sXBYQQ4ZF5G5p="p); txt"
Content-Type: text/plain
------WebKitFormBoundarywr3X7sXBYQQ4ZF5G--
了解了發送格式的細節之後, 下一步就是使用nodejs來編程實現,簡單來講, 就是按照格式把資料發送給服務端就行了。
const http = require('http'); const fs = require('fs'); //post地址为本地服务的一个php,用于测试上传是否成功 var options = { hostname: 'localhost', port: 80, path: '/get.php', method: 'POST' } //生成分隔数据 var boundaryKey = '----WebKitFormBoundaryjLVkbqXtIi0YGpaB'; //读取需要上传的文件内容 fs.readFile('./upload.txt', function (err, data) { //拼装分隔数据段 var payload = '--' + boundaryKey + '\r\n' + 'Content-Disposition:form-data; name="myfile"; filename="upload.txt"\r\n' + 'Content-Type:text/plain\r\n\r\n'; payload += data; payload += '\r\n--' + boundaryKey + '--'; //发送请求 var req = http.request(options, function (res) { res.setEncoding('utf8'); res.on('data', function (chunk) { console.log('body:' + chunk); }); }); req.on('error', function(e) { console.error("error:"+e); }); //把boundary、要发送的数据大小以及数据本身写进请求 req.setHeader('Content-Type', 'multipart/form-data; boundary='+boundaryKey+''); req.setHeader('Content-Length', Buffer.byteLength(payload, 'utf8')); req.write(payload); req.end(); });
本文重點在於了解協定並且用程式碼實作出來, 程式碼組織上面還有很多最佳化的地方。
最後在本地apache,簡單寫一個php來保存上傳的文件來用作測試:
<?php $filePath = './upload.txt'; move_uploaded_file($_FILES['myfile']['tmp_name'] , $filePath); echo "ok"; ?>
另外,根據RFC 1867 還可以實現一次上傳多個文件的功能,在這個上傳多個文件不詳述, 需要的話可以詳細參考RFC 1867來實現。
以上所述是小編給大家介紹的Node.js實作檔案上傳,希望對大家有幫助,如果大家有任何疑問請給我留言,小編會及時回覆大家的。在此也非常感謝大家對PHP中文網的支持!
更多Node.js實作檔案上傳相關文章請關注PHP中文網!