front-end-pigs / blog

博客
2 stars 0 forks source link

文件上传header字段content-type设置问题 #1

Open jangdelong opened 5 years ago

jangdelong commented 5 years ago

问题描述

文件通过FormData的方式去上传,头部字段content-type字段设置为multipart/form-data,会导致后端无法解析文件内容,导致文件上传失败。

image image

解决方案

文件上传header字段无需设置multipart/form-data,因为如果设置了multipart/form-data将导致content-type没有边界boundary,从而使得后端无法解释文件流。因为这种情况下建议,header不对content-type进行设置,使用浏览器默认匹配的content-type。

5cef4547ea3b4a792301f475_origin

ps,个人封装的ajax库代码如下:

const ajax = opt => {
  opt = opt || {}
  opt.method = opt.method.toUpperCase() || 'POST'
  opt.url = opt.url || ''
  opt.async = opt.async || true
  opt.data = opt.data || {}
  opt.success = opt.success || (() => {})
  opt.fail = opt.fail || (() => {})
  opt.header = opt.header || {}
  opt.contentType = opt.contentType || ''
  const xmlHttp = new XMLHttpRequest()
  let params = []
  if (typeof opt.data === 'object') {
    for (let key in opt.data){
      params.push(key + '=' + opt.data[key])
    }
  }
  let postData = params.join('&')

  if (opt.method.toUpperCase() === 'POST') {
    xmlHttp.open(opt.method, opt.url, opt.async)
    for (const headerKey in opt.header) {
      xmlHttp.setRequestHeader(headerKey, opt.header[headerKey])
    }

    if (opt.data.constructor === FormData) {
      xmlHttp.setRequestHeader('Accept', '*/*')
      // 注释掉以下一行代码
      // xmlHttp.setRequestHeader('Content-Type', 'multipart/form-data')
      xmlHttp.send(opt.data)
    } else if (/application\/x-www-form-urlencoded/i.test(opt.contentType)) {
      xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8')
      xmlHttp.send(postData)
    } else {
      xmlHttp.setRequestHeader('Content-Type', 'application/json;charset=utf-8')
      xmlHttp.send(JSON.stringify(opt.data))
    }
  } else if (opt.method.toUpperCase() === 'GET') {
    if (postData) {
      if (opt.url.indexOf('?') > -1) {
        opt.url += '&' + postData
      } else {
        opt.url += '?' + postData
      }
    }
    xmlHttp.open(opt.method, opt.url, opt.async)
    for (const headerKey in opt.header) {
      xmlHttp.setRequestHeader(headerKey, opt.header[headerKey])
    }
    xmlHttp.send(null)
  }
  xmlHttp.onreadystatechange = function () {
    if (xmlHttp.readyState === 4) {
      if (xmlHttp.status === 200) {
        opt.success(xmlHttp.responseText)
      } else {
        opt.fail(xmlHttp.responseText)
      }
    }
  }
}