Node.js模拟发送get、post请求

首先,安装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"的格式,导致数据混乱。

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值