Ich bin bei der Arbeit auf eine solche Nachfrage gestoßen, dass ich NodeJS zum Hochladen von Dateien verwenden musste. Bisher wusste ich, wie man Dateien über einen Browser hochlädt. Nach einiger Google-Suche wurde mir klar, dass der Browser lediglich das http-Protokoll verwendet, um Daten an den Server zu übertragen. Das spezifische Protokoll ist „RFC 1867 – Formularbasierter Datei-Upload in HTML“. Mit dem Browser-Protokoll können wir zunächst sehen, welche Daten der Browser an den Server sendet, und dann die Upload-Funktion auf die gleiche Weise implementieren. Apropos Formular-Upload-Dateien: Jeder sollte damit vertraut sein:
<form action="http://www.qq.com/" method="post"> <input type="text" name="text1" /><br /> <input type="text" name="text2" /><br /> <input type="submit" /> </form>
Senden Sie Daten wie folgt:
POST http://www.qq.com/ HTTP/1.1
Inhaltslänge: 23
Inhaltstyp: application/x-www-form-urlencoded; world
Es ist erwähnenswert, dass Content-Type standardmäßig application/x-www-form-urlencoded ist, sodass die Nachricht URL-codiert ist. „Hallo“ würde beispielsweise als %E4%BD%A0%E5%A5%BD kodiert werden.
Als nächstes schauen wir uns an, wie man über das Formular hochlädt. Jeder sollte damit vertraut sein:
<form action="http://www.qq.com" method="post" enctype="multipart/form-data"> <input type="file" name="myfile" /> <input type="submit" value="submit" /> </form>
POST http: //www.qq.com/ HTTP/1.1
Host: www.qq.com
Inhaltslänge: 199
------WebKitFormBoundarywr3X7sXBYQQ4ZF5G
Hallo Welt
------WebKitFormBoundarywr3X7sXBYQQ4ZF5G--
Gemäß der Definition von RFC 1867 müssen wir ein Stück Grenzdaten generieren Daten können nicht an anderer Stelle im Inhalt angezeigt werden. Der Generierungsalgorithmus kann in jedem Browser unterschiedlich sein. Nach der Generierung der getrennten Daten können die getrennten Daten im Inhalt platziert werden. Der Typ des Headers, der an den Server gesendet wird, ist Content-Type oben: multipart/form-data; border=----WebKitFormBoundarywr3X7sXBYQQ4ZF5G. Darüber hinaus muss der hochgeladene Inhalt mithilfe von getrennten Daten in mehrere Segmente unterteilt werden Das Datensegment enthält den Dateinamen beim Hochladen. Der Server verwendet diesen Namen, um die Datei zu empfangen. In diesem Beispiel handelt es sich um den Dateityp „Text/Plain“. Das PNG-Bild ist image/png. Eine Leerzeile nach dem Dateityp ist der Inhalt der hochgeladenen Datei. In diesem Beispiel wird der besseren Verständlichkeit halber eine Textdatei hochgeladen, sodass der Inhalt direkt angezeigt werden kann, wenn eine Bilddatei hochgeladen wird ist eine Binärdatei, Fiddler. Sie zeigt nur verstümmelte Zeichen an. Nachdem der Inhalt der Datei beendet ist, gibt es eine Leerzeile plus Grenzdaten.
Der Schwerpunkt dieses Artikels liegt darauf, das Protokoll zu verstehen und es mit Code zu implementieren. Es gibt viele Optimierungen in der Codeorganisation.
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(); });
Schreiben Sie abschließend im lokalen Apache einfach eine PHP-Datei, um die hochgeladene Datei zum Testen zu speichern:
Darüber hinaus können Sie gemäß RFC 1867 auch die Funktion zum gleichzeitigen Hochladen mehrerer Dateien implementieren. Dies wird hier nicht im Detail beschrieben. Einzelheiten finden Sie in RFC 1867.
<?php $filePath = './upload.txt'; move_uploaded_file($_FILES['myfile']['tmp_name'] , $filePath); echo "ok"; ?>
Das Obige ist die vom Herausgeber eingeführte Node.js-Implementierung des Datei-Uploads. Wenn Sie Fragen haben, hinterlassen Sie mir bitte eine Nachricht pünktlich zu Ihnen. Ich möchte mich auch bei Ihnen allen für Ihre Unterstützung der chinesischen PHP-Website bedanken!
Weitere Artikel zur Implementierung des Datei-Uploads durch Node.js finden Sie auf der chinesischen PHP-Website!