Maison >interface Web >js tutoriel >Node.js implémente le téléchargement de fichiers
J'ai rencontré une telle demande au travail. J'avais besoin d'utiliser nodejs pour télécharger des fichiers. Avant, je savais seulement comment télécharger des fichiers via un navigateur. Utiliser nodejs équivaut à simuler le comportement d'un navigateur. Après quelques recherches sur Google, j'ai réalisé que le navigateur utilise simplement le protocole http pour transmettre des données au serveur. Le protocole spécifique est "RFC 1867 - Téléchargement de fichiers basé sur un formulaire en HTML". le protocole du navigateur, nous pouvons d'abord voir quelles données le navigateur envoie au serveur, puis nous pouvons implémenter la fonction de téléchargement de la même manière. En parlant de formulaire de téléchargement de fichiers, tout le monde devrait le connaître :
<form action="http://www.qq.com/" method="post"> <input type="text" name="text1" /><br /> <input type="text" name="text2" /><br /> <input type="submit" /> </form>
Envoyez des données comme ceci :
POST http://www.qq.com/ HTTP/1.1
Content-Length : 23
Content -Type : application/x-www-form-urlencoded; charset=UTF-8
text1=hello&text2= world
Il convient de noter que Content-Type est par défaut application/x-www-form-urlencoded, le message sera donc codé en URL. Par exemple, « Bonjour » sera codé comme Bonjour.
Voyons ensuite comment télécharger via le formulaire. Tout le monde devrait être familier avec ceci :
<form action="http://www.qq.com" method="post" enctype="multipart/form-data"> <input type="file" name="myfile" /> <input type="submit" value="submit" /> </form>
Créez ensuite un nouveau fichier texte upload.txt avec uniquement les mots bonjour tout le monde et téléchargez-le, nous l'utiliserons Utilisez fiddler pour capturer le package, et vous constaterez que les données envoyées sont un peu plus compliquées (de nombreuses autres lignes de requête non pertinentes ont été supprimées, telles que le contrôle du cache et les cookies) :
POST http : //www.qq.com/ HTTP/1.1
Content-Length : 199
Content-Type : multipart/form-data border=; ----WebKitFormBoundarywr3X7sXBYQQ4ZF5G
------WebKitFormBoundarywr3X7sXBYQQ4ZF5G
Content-Disposition : form-data="myfile" ; /plain
bonjour tout le monde
------WebKitFormBoundarywr3X7sXBYQQ4ZF5G--
Selon la définition de la RFC 1867, nous devons générer une donnée de limite. les données ne peuvent pas apparaître ailleurs dans le contenu. Cela peut être défini vous-même. L'algorithme de génération dans chaque navigateur peut être différent. La limite ci-dessus consiste à séparer les données. Une fois les données séparées générées, les données séparées peuvent être placées dans le contenu. Type de l'en-tête et envoyé au serveur, c'est-à-dire Content-Type ci-dessus : multipart/form-data; border=----WebKitFormBoundarywr3X7sXBYQQ4ZF5G De plus, le contenu téléchargé doit être séparé en plusieurs segments à l'aide de données délimitées, et chacun. Le segment de données contient le nom du fichier. Il y a également le nom lors du téléchargement. Le serveur utilise ce nom pour recevoir le fichier, et le type de fichier Content-Type. Dans cet exemple, il s'agit de text/plain. L'image png est image/png. Une ligne vide après le type de fichier correspond au contenu du fichier téléchargé. Dans cet exemple, pour faciliter la compréhension, un fichier texte est téléchargé, afin que le contenu puisse être affiché directement si un fichier image est téléchargé. est un fichier binaire, fiddler. Il affiche simplement des caractères tronqués. Une fois le contenu du fichier terminé, il y a une ligne vide plus des données de limite.
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(); });L'objectif de cet article est de comprendre le protocole et de l'implémenter avec du code. Il existe de nombreuses optimisations dans l'organisation du code.
Enfin, dans Apache local, écrivez simplement un php pour enregistrer le fichier téléchargé pour le tester :
<?php $filePath = './upload.txt'; move_uploaded_file($_FILES['myfile']['tmp_name'] , $filePath); echo "ok"; ?>De plus, selon la RFC 1867, vous pouvez également implémenter la fonction de téléchargement de plusieurs fichiers en même temps. Cela ne sera pas décrit en détail ici. Si nécessaire, vous pouvez vous référer à la RFC 1867 pour plus de détails.
Ce qui précède est l'implémentation Node.js du téléchargement de fichiers introduite par l'éditeur. J'espère que cela vous sera utile. Si vous avez des questions, veuillez me laisser un message et l'éditeur vous répondra. à vous à temps. Je voudrais également vous remercier tous pour votre soutien au site Web PHP chinois !