Faster, Higher, Stronger
更快,更高,更强

FormData的使用及请求头分析

本文核心内容:

  1. FormData简介
  2. FormData的使用(jQuery、XHR、fetch、axios,及对应源码解析)
  3. 请求头分析

一、FormData简介

XMLHttpRequest Level 2添加了一个新的接口FormData.利用FormData对象,我们可以通过JavaScript用一些键值对来模拟一系列表单控件,我们还可以使用XMLHttpRequest的send()方法来异步的提交这个”表单”.比起普通的ajax,使用FormData的最大优点就是我们可以异步上传一个二进制文件.

——https://developer.mozilla.org/zh-CN/docs/Web/API/FormData

二、FormData的使用

要构建一个FormData数据的话,只需要用类似下面的伪代码:

const fd = new FormData()
fd.append('key', 'valueOfTheKey')
// 注意,传文件时,第二个参数是一个文件blob对象,可以通过传入第三个参数来指定文件名(filename)
fd.append('file', fileblob, 'optionalFileName')

跟jQuery一起使用:

注意:要发送FormData数据的话,jquery ajax的配置里processData和contentType的值需要显性得设置为false。

$.ajax(merge({
  type: 'POST',
  accepts: 'application/json',
  contentType: requestData instanceof FormData ? false : 'application/x-www-form-urlencoded;charset=utf-8',
  url: apiPrefix + endPoint,
  dataType: 'json',
  processData: !(requestData instanceof FormData),
  data: (() => {
    if (requestData instanceof FormData) {
      return requestData
    }
    const d = new Date().getTime()
    return {
      requestTime: d,
      sessionToken: hexMd5((d + '').substring((d + '').length - 8)),
      requestBody: JSON.stringify(requestData)
    }
  })()
}, options))

跟axios一起使用:

export const postData = (
  url: string,
  requestData: Object,
  ajaxHeaderOptions?: Object,
): any => {
  return axios({
    ...axiosConfig,
    url,
    method: 'post',
    data: (() => {
      if (requestData instanceof FormData) {
        return requestData;
      } else {
        return qs.stringify((() => {
          const d = new Date().getTime();
          return {
            requestTime: d,
            sessionToken: hexMd5((d + '').substring((d + '').length - 8)),
            requestBody: JSON.stringify(requestData),
          }
        })());
      }
    })(),
    headers: {
      'Accept': 'application/json',
      'X-Requested-With': 'XMLHttpRequest',
      ...(() => {
        if (requestData instanceof FormData) {
          return {};
        } else {
          return { 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8' };
        }
      })(),
      ...(ajaxHeaderOptions || {}),
    },
  }).catch((error: any): any => {
    if (error.response) {
      // The request was made and the server responded with a status code
      // that falls out of the range of 2xx
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else if (error.request) {
      // The request was made but no response was received
      // `error.request` is an instance of XMLHttpRequest in the browser and an instance of
      // http.ClientRequest in node.js
      console.log(error.request);
    } else {
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
    }
    console.log(error.config);
  })
};

三、请求头分析

这块主要的内容就是请求头里Content-Type里有个boundary,它的值在Request Payload里出现了好多次。它的作用就是作为请求参数里各个key-value对的分界线(boundary)。前文我们有说过append方法的第三个参数可以指定filename,如果我们没传第三个参数的话,像上面截图里filename=”blablabla.jpeg”的部分就不会出现了。有时候这个地方接口联调失败有可能是后台取了filename但是前端没有指定filename。

赞(1) 打赏
未经允许不得转载:峰间的云 » FormData的使用及请求头分析

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏