首先,安装request模块
npm install -s request
随后创建test.js文件。
编辑test.js
1.引用request
let request = require("request");
2.get请求
//get请求
request('http://127.0.0.1:8080/get?id=1&pwd=abc123', function (error, response, body) {
if (!error) {
console.log(body);
}
});
运行node D:/test就可以进行测试了。输出的body就是服务器返回的Content内容。
3.post请求
post请求有多种数据格式。
3.1 application/x-www-form-urlencoded
//post请求
request.post({
url: "http://127.0.0.1:8080/post",
headers: {
"content-type": "application/x-www-form-urlencoded"
},
form: {
id: 1 // post请求的参数
}
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
});
其中,"application/x-www-form-urlencoded"是最常见的post请求头,它的实际参数格式为"key1=value1&key2=value2&key3=value3",而其他字符会被转换为utf-8编码
根据我们要传的数据格式,我们可以修改headers属性:
headers:{
"content-type": "application/x-www-form-urlencoded"
// "content-type": "multipart/form-data"
// "content-type": "application/json"
// "content-type": "application/xml"
}
这里要提醒一下,如果在请求中设置了form属性值,则不论请求头设置为什么,都会设置为"application/x-www-form-urlencoded"。
3.2 multipart/form-data
"multipart/form-data"为一种特殊的提交方式,一般用于文件传输。
传递的内容可以是字符串、Buffer、文件、文件流、以及自定义文件。
let formData = {
// 字符串
my_field: 'This is my value.',
// Buffer
my_buffer: Buffer.from([1, 2, 3, 4]),
// 文件
my_file: fs.createReadStream(__dirname + '/example.jpg'),
// 文件流
attachments: [
fs.createReadStream(__dirname + '/example1.jpg'),
fs.createReadStream(__dirname + '/example2.jpg')
],
// 自定义文件格式
custom_file: {
value: fs.createReadStream('/dev/test'),
options: {
filename: 'test.jpg',
contentType: 'image/jpeg'
}
}
};
这里我们取一部分数据:
var formData = {
my_field: 'my_value',
my_buffer: Buffer.from([1,2,3]),
};
因此请求发送如下:
//post请求
request.post({
url: "http://127.0.0.1:8080/",
headers: {
"content-type": "multipart/form-data",
},
formData: formData
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
});
发送的请求头:
{
'content-type': 'multipart/form-data; boundary=--------------------------358029067038531214467368',
host: '127.0.0.1:3000',
'content-length': '322',
connection: 'close'
}
服务器端直接输出的结果为:
----------------------------473332229673559460560507
Content-Disposition: form-data; name="my_field"
my_value
----------------------------473332229673559460560507
Content-Disposition: form-data; name="my_buffer"
Content-Type: application/octet-stream
----------------------------473332229673559460560507--
这里第二部分的内容没有显示,实际上打印出来的是两个方框,也就是乱码。此外,request模块默认将Buffer设置为"application/octet-stream"格式,也就是文件传输的格式。
那么为什么会产生乱码呢?参见https://blog.csdn.net/Z_ammo/article/details/103684432
实际上"multipart/form-data"还需要设置额外的内容,只不过这部分可以由request模块包办。实际上的Content-Type如下:
"Content-Type": `multipart/form-data; boundary=${bound}`
${bound}是一个自定义的分隔符,可以为任意字符串,但是一般要写的复杂一点,以防止与文本冲突,比如我们可以设置:
let bound = '--7382421790MultipartBoundary';
这样,一个"multipart/form-data"的body示例如下:
----7382421790MultipartBoundary
Content-Disposition: form-data; name="id"
user_123
----7382421790MultipartBoundary
Content-Disposition: form-data; name="pwd"
abc123
----7382421790MultipartBoundary--
注意数据通过${bound}分割成多个数据段,尤其是每个分隔符前面要额外加'--',且最后一个分隔符后面也要加'--'作为结束标志。
我们当然可以自定义"multipart/form-data"请求及其分隔符,但是请注意,要想自定义分隔符,必须将内容写在'body'属性中,而不能使用formData,因为使用formData之后,request模块会自动分配分隔符,而忽略用户的设置。
而且一旦设置formData属性,则会忽略用户设置的请求头,而总是使用"multipart/form-data"。
当数据为'multipart/form-data'时,传输的数据为二进制数据流,所以后端获取请求主体的方式也要有所改变。以express服务器为例:
req.on('data', (data) => {
console.log(data.toString());
});
当然buffer作为二进制数据流,可以传递很大的文件,因此可能会多段传输,需要额外处理:
let buf = [];
req.on('data', (data) => {
buf.push(data);
});
req.on('end', () => {
buf = Buffer.concat(buf);
console.log(buf.toString());
});
3.3 application/json
"application/json"是用来处理当参数为一个多层嵌套的对象时的问题。虽然"application/x-www-form-urlencoded"也可以实现参数的嵌套,但是写法和解析时都比较麻烦。
"application/json"的参数写在body属性中,express服务器读取数据也是在Response.body属性中。
//post请求
request.post({
url: "http://127.0.0.1:3000/",
headers: {
"content-type": "application/json",
},
body: '{"data":"abc"}'
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
});
3.4 application/xml
reuquest模块的官方文档并没有提供"application/xml"请求方式,但是我们依然可以模拟发送xml格式的数据。
发送xml请求要将xml数据以字符串的形式写在request的body属性中,同时服务器端收到的是Buffer数据,可能要分段获取。
//post请求
request.post({
url: "http://127.0.0.1:3000/",
headers: {
"content-type": "application/xml"
},
body: '<data>userData</data>'
}, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body);
}
});
拓展:如果request模块同时设置了form和formData会发生什么?
读者可以自行尝试。结果证明:当二者同时存在时,会将请求头设置为"application/x-www-form-urlencoded",且数据通过Response.body获取,没有Buffer数据。但是formData的内容会出现在form的内容之前,且formData依然是"multipart/form-data"的格式,导致数据混乱。