349989153 / 349989153.github.io

My personal blog.
0 stars 0 forks source link

手撕FormData #9

Open 349989153 opened 4 years ago

349989153 commented 4 years ago

小程序里没有FormData类,所以POST方法如果要传multipart/form-data就会报错。

而npm上的formdata-polyfill,类似 https://github.com/form-data/form-data 或者https://github.com/jimmywarting/FormData 都不好用

好在有人探究出来 https://developers.weixin.qq.com/community/develop/article/doc/0000cc0e5bc5d093c6f8be17254c13 可以手动拼装出FormData格式的字符串,并且成功调用。

以下附代码:

// 手动拼接FormData字符串
// 函数边界处理没怎么做,各位可自行补充
function createFormData(params = {}, boundary = '') {
  let result = '';
  for (let i in params) {
    result += `\r\n--${boundary}`;
    result += `\r\nContent-Disposition: form-data; name="${i}"`;
    result += '\r\n';
    result += `\r\n${params[i]}`
  }
  // 如果obj不为空,则最后一行加上boundary
  if (result) {
    result += `\r\n--${boundary}`
  }
  return result
}

// 通用post请求
export const post = function (url, params) {
  return new Promise(function (resolve, reject) {
    // 生成一个boundary字符串
    const boundary = `----FooBar${new Date().getTime()}`;
    const formData = createFormData(params, boundary);
    console.log(formData);
    Taro.request({ // 这里我用的taro,改成wx.request也一样
      url,
      method: 'POST',
      credentials: 'include', //设置传递cookies
      dataType: 'json',
      header: {
        'Accept': 'application/json',
        'Content-Type': `multipart/form-data; boundary=${boundary}`,
      },
      data: formData,
      timeout: 5000,
      success: function (res) {
        resolve(res.data);
      },
      fail: function (error) {
        reject(error);
      }
    })
  });
}
349989153 commented 4 years ago

用postman发个formdata请求,我们可以看到数据长这样:

Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="mobile"

13800138000
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="name"

张三
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="address"

地球
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="weappid"

abcdefghijklmn
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="id"

107
------WebKitFormBoundary7MA4YWxkTrZu0gW--

仔细观察以下,就可以总结出上面的拼装规则了。 其中,数据体中boundary,是Content-Type中的boundary前面加--