请问如何用Nodejs通过post发送multipart/form-data类型的http请求?

请问如何用Nodejs通过post发送multipart/form-data类型的http请求?

请问如果用nodejs通过post发送multipart/form-data类型的http请求?

网络上搜索的都是解析multipart/form-data表单的,express已经提供了较好的支持,那NODEJS如果后台模拟发送multipart/form-data类型消息呢?上传个图片给接口方。

比如如何在后台用https.request模拟类似请求?纠结几天了,请大侠帮帮忙哦。

<form name='sendMsgToWxByPost' action='https://api.com/media?access_token=AAA' method="post" enctype="multipart/form-data" >

<input type=“file” name=“media” /> </form>

我知道application/x-www-form-urlencoded类型的请求是这样模拟的。

var post_data = querystring.stringify({
    type : "text",
    content: content

});

//1、创建消息 var options = { host: ‘api.com’, port: 443, path: ‘/messages?access_token=’+accessToken, method: ‘POST’, headers: { ‘Content-Type’: ‘application/x-www-form-urlencoded’, ‘Content-Length’: post_data.length } };

var reqHttps = https.request(options, function(resHttps) { console.log("statusCode: ", resHttps.statusCode); console.log("headers: ", resHttps.headers);

 	resHttps.setEncoding('utf8');
 	resHttps.on('data', function(body1) {
    console.log("body:"+body1);
    }

// write data to request body reqHttps.write(post_data); reqHttps.end(); reqHttps.on(‘error’, function(e) { console.error(“error:”+e); return “系统异常:”+e.message; });


9 回复

当然可以。要使用Node.js通过POST请求发送multipart/form-data类型的HTTP请求,我们可以使用第三方库如form-dataaxios来简化这一过程。下面是一个具体的实现步骤和示例代码。

实现步骤

  1. 安装必要的库:首先需要安装form-dataaxios
  2. 构建请求体:使用form-data库来构建multipart/form-data格式的数据。
  3. 发送请求:使用axios来发送带有构建好的请求体的POST请求。

示例代码

安装依赖

npm install form-data axios

构建并发送请求

const FormData = require('form-data');
const axios = require('axios');

async function sendMultipartFormDataRequest() {
    // 创建一个FormData实例
    const formData = new FormData();

    // 添加文件到FormData中
    formData.append('media', fs.createReadStream('/path/to/your/image.jpg'));

    try {
        // 发送POST请求
        const response = await axios.post(
            'https://api.com/media?access_token=AAA',
            formData,
            {
                headers: formData.getHeaders()
            }
        );

        // 输出响应结果
        console.log(response.data);
    } catch (error) {
        console.error('Error:', error.response ? error.response.data : error.message);
    }
}

// 调用函数
sendMultipartFormDataRequest();

解释

  • FormData:这是一个用于构造multipart/form-data请求体的类,通常用于处理文件上传等场景。
  • axios.post:使用axios发送POST请求,并传递FormData对象作为数据部分。formData.getHeaders()会自动设置正确的Content-Type头。
  • fs.createReadStream:从指定路径读取文件,并将其作为文件字段添加到FormData中。

以上代码展示了如何使用Node.js发送包含文件的multipart/form-data类型的POST请求。这种方式简洁且易于理解,同时避免了手动构建复杂的HTTP请求体。


post_data 照着这里的格式发就行了: http://www.w3.org/TR/html401/interact/forms.html#h-17.13.4.2

我本来想在往微博发图片的功能里用的,不过做到一半改用了另一个通过地址上传图片的接口。

发个半成品的代码给你参考下:

var https = require('https');
var fs = require('fs');
var util = require('util');
var path = require('path');

var BOUNDARYPREFIX = ‘nbglme’;

var mkpic = function (pic, fn) { var mimes = { ‘.png’: ‘image/png’, ‘.gif’: ‘image/gif’, ‘.jpg’: ‘image/jpeg’, ‘.jpeg’: ‘image/jpeg’ }; var ext = path.extname(pic); var mime = mimes[ext]; if (!mime) return;

fs.readFile(’/home/bnlt/’+pic, function (err, data) { content = util.format(‘Content-Disposition: form-data; name=“pic”; filename="%s"\r\n’, pic); content += util.format(‘Content-Type: %s\r\n\r\n’, mime); content += data; fn(content); }); }

var mkfield = function (field, value) { return util.format(‘Content-Disposition: form-data; name="%s"\r\n\r\n%s’, field, value); }

exports.post = function (param, onsuccess, onfailer) { if (param.pic) { mkpic(param.pic, function (pic) { var data = [pic]; delete param.pic; for (var i in param) { data.push(mkfield(i, param[i])); }

  var max = 9007199254740992;
  var dec = Math.random() * max;
  var hex = dec.toString(36);
  var boundary = BOUNDARYPREFIX + hex;

  var body = util.format('Content-Type: multipart/form-data; boundary=%s\r\n\r\n', boundary)
             + util.format('--%s\r\n', boundary)
             + data.join(util.format('\r\n--%s\r\n', boundary))
             + util.format('\r\n--%s', boundary);

  console.log(body);
});

} }

最后面 console.log(body) 中 body 里的数据就是要发送的数据

看了一下,确实能够方便的满足此类需求,相见恨晚啊

嗯。昨天我也按照这样思路写的,模拟发post。发现Content-Length的计算结果和直接在IE浏览器提交抓包得到的数据差四个字符,很是诧异,不过总算可以上传给接口方了。是参考的这三篇文章,分享下啊: enter link description here enter link description here enter link description here

我也试试哈

自己写的方法可以跑了,贴出来。

//发送单条消息给接口方 app.post("/sendMsgToAByPost",function(req, res, next) {

//我的帖子:http://cnodejs.org/topic/4ffed8544764b729026b1da3
//http://yefeng.iteye.com/blog/315847
//http://stackoverflow.com/questions/5744990/how-to-upload-a-file-from-node-js
//http://stackoverflow.com/questions/9943010/node-js-post-file-to-server

console.log(req.files); console.log(req.files.media.size); var boundaryKey = Math.random().toString(16); //随机数,目的是防止上传文件中出现分隔符导致服务器无法正确识别文件起始位置 console.log(boundaryKey);

var options = {
		host: 'api.com',
		port: 443,
		path: '/media?type=image&amp;access_token='+accessToken,
		method: 'POST'
};

var reqHttps = https.request(options, function(resHttps) {
	console.log("statusCode: ", resHttps.statusCode);
	console.log("headers: ", resHttps.headers);
	
	resHttps.on('data', function(body1) {
	console.log("body:"+body1);
	});
});
var payload = '--' + boundaryKey + '\r\n'
// use your file's mime type here, if known
+ 'Content-Type: image/jpeg\r\n' 
// "name" is the name of the form field
// "filename" is the name of the original file
+ 'Content-Disposition: form-data; name="media"; filename="aaa.jpg"\r\n'
+ 'Content-Transfer-Encoding: binary\r\n\r\n';
console.log(payload.length);
var enddata  = '\r\n--' + boundaryKey + '--';
console.log('enddata:'+enddata.length);
reqHttps.setHeader('Content-Type', 'multipart/form-data; boundary='+boundaryKey+'');
reqHttps.setHeader('Content-Length', Buffer.byteLength(payload)+Buffer.byteLength(enddata)+req.files.media.size);

reqHttps.write(payload);

var fileStream = fs.createReadStream("D:\\aaa.jpg", { bufferSize: 4 * 1024 });
fileStream.pipe(reqHttps, {end: false});
fileStream.on('end', function() {
	// mark the end of the one and only part
	reqHttps.end(enddata); 
	
});

reqHttps.on('error', function(e) {
	console.error("error:"+e);
});

});

不明觉厉!

学习了,收藏。

要使用 Node.js 发送 multipart/form-data 类型的 HTTP POST 请求,你可以使用第三方库 form-data 来构造请求体。以下是一个简单的示例代码:

const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');

// 创建 form-data 对象
const form = new FormData();
form.append('media', fs.createReadStream('/path/to/your/image.jpg'));

// 使用 axios 发送请求
axios.post('https://api.com/media?access_token=AAA', form, {
    headers: form.getHeaders()
})
.then(response => {
    console.log('Response:', response.data);
})
.catch(error => {
    console.error('Error:', error.response ? error.response.data : error.message);
});

解释

  1. 安装依赖

    npm install axios form-data
    
  2. 创建 FormData 对象:使用 FormData 库来构建请求体。

  3. 添加文件:使用 append 方法将文件添加到 FormData 对象中。

  4. 发送请求:使用 axios 发送 POST 请求,并将 FormData 对象作为请求体。

这样就可以模拟一个包含文件的 multipart/form-data 类型的 HTTP POST 请求。如果你不想使用 axios,也可以使用 https.request,但需要手动处理 multipart/form-data 的构造,这会复杂很多。

回到顶部