Henry Henry
  • JavaScript
  • TypeScript
  • Vue
  • ElementUI
  • React
  • HTML
  • CSS
  • 技术文档
  • GitHub 技巧
  • Nodejs
  • Chrome
  • VSCode
  • Other
  • Mac
  • Windows
  • Linux
  • Vim
  • VSCode
  • Chrome
  • iTerm
  • Mac
  • Obsidian
  • lazygit
  • Vim 技巧
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • Vue 资源
GitHub (opens new window)

Henry

小学生中的前端大佬
  • JavaScript
  • TypeScript
  • Vue
  • ElementUI
  • React
  • HTML
  • CSS
  • 技术文档
  • GitHub 技巧
  • Nodejs
  • Chrome
  • VSCode
  • Other
  • Mac
  • Windows
  • Linux
  • Vim
  • VSCode
  • Chrome
  • iTerm
  • Mac
  • Obsidian
  • lazygit
  • Vim 技巧
  • 分类
  • 标签
  • 归档
  • 网站
  • 资源
  • Vue 资源
GitHub (opens new window)
  • JavaScript

  • TypeScript

  • Vue

    • Vue 编码指南
    • vue-cli 启动本地服务局域网不能访问的原因分析
    • 解决 Vue 相同路由参数不同不会刷新的问题
    • 解决 vuex requires a Promise polyfill in this browser 问题
    • 关于父组件通过 v-on 接收子组件多个参数的一点研究
    • Vue $attrs 和 $listeners
    • Vue axios 发送 Form Data 数据格式请求
      • 一、 设置单个的 POST 请求为 Form Data 格式
        • 方法一: 修改 headers 和 transformRequest
        • 方法二: 利用 URLSearchParams, 不兼容 IE, 貌似安卓 / iOS 低版本也不兼容
        • 方法三: 利用 FormData, 兼容性比 URLSearchParams 好一点
        • 方法四: 利用 qs
      • 二、 全局设置 POST 请求为 Form Data 格式
    • Vue 开发技巧
    • Vue 动态路由
    • Vue 集成 UEditor 富文本编辑器
    • Vue 修饰符
    • Vue 问题集合
    • Vue props 传多值的问题
    • vue-router 在 IE11 下手动更改 URL 的 hash 不会触发路由
    • vue-router 路由参数刷新消失的问题
    • 那些年被我们忽略的 vue 语法
    • vue 生命周期深入
    • vue 组件通信深入
    • vue 组件通信深入 Vuex
    • vue项目移动端、pc端适配方案
    • vuepress 如何引入 vuex
  • ElementUI

  • React

  • AntD

  • 前端
  • Vue
Henry
2019-03-20
目录

Vue axios 发送 Form Data 数据格式请求

axios 默认是 Payload 格式数据请求, 但有时候后端接收参数要求必须是 Form Data 格式的, 所以我们就得进行转换.

Payload 和 Form Data 的主要设置是根据请求头的 Content-Type 的值来的.

  • Payload Content-Type: 'application/json; charset=utf-8'

  • Form Data Content-Type: 'application/x-www-form-urlencoded'

# 一、 设置单个的 POST 请求为 Form Data 格式

# 方法一: 修改 headers 和 transformRequest

axios({
  method: 'post',
  url: 'http://localhost:8080/login',
  data: {
    username: this.loginForm.username,
    password: this.loginForm.password
  },
  transformRequest: [
    function(data) {
      let ret = ''
      for (let it in data) {
        // 如果 data[it] 是一个对象, 需要先使用 JSON.stringify, 再使用 encode
        ret += encodeURIComponent(it) + '=' + encodeURIComponent(data[it]) + '&'
      }
      ret = ret.substring(0, ret.lastIndexOf('&'))
      return ret
    }
  ],
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

# 方法二: 利用 URLSearchParams (opens new window), 不兼容 IE, 貌似安卓 / iOS 低版本也不兼容

const params = new URLSearchParams()
params.append('username', this.loginForm.username)
params.append('password', this.loginForm.password)
axios({
  method: 'post',
  url: 'http://localhost:8080/login',
  data: params
})
1
2
3
4
5
6
7
8

# 方法三: 利用 FormData (opens new window), 兼容性比 URLSearchParams 好一点

const params = new FormData()
params.append('username', this.loginForm.username)
params.append('password', this.loginForm.password)
axios({
  method: 'post',
  url: 'http://localhost:8080/login',
  data: params
})
1
2
3
4
5
6
7
8

# 方法四: 利用 qs

const params = {
  username: this.loginForm.username,
  password: this.loginForm.password
}
axios({
  method: 'post',
  url: 'http://localhost:8080/login',
  data: qs.stringify(params)
})
1
2
3
4
5
6
7
8
9

# 二、 全局设置 POST 请求为 Form Data 格式

因为像上面那样每个请求都要配置 transformRequest 和 Content-Type 非常的麻烦, 重复性代码也很丑陋, 所以通常都会进行全局设置. 具体代码如下

import axios from 'axios'
import qs from 'qs'

// 实例对象
let instance = axios.create({
  timeout: 6000,
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded'
  }
})

// 请求拦截器
instance.interceptors.request.use(
  config => {
    config.data = qs.stringify(config.data) // 转为 formdata 数据格式
    return config
  },
  error => Promise.error(error)
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

就是我们在封装 axios 的时候, 设置请求头 Content-Type 为   application/x-www-form-urlencoded . 然后在请求拦截器中, 通过 qs.stringify() 进行数据格式转换, 这样每次发送的 POST 请求都是 Form Data 格式的数据了. 其中 qs 模块是安装 axios 模块的时候就有的, 不用另行安装, 通过 import 引入即可使用.

上面的方法会将全部 post 请求都转换成 Form Data 格式了, 实际上并不是所有请求都是这样的. 我们可以根据一个参数判断是否需要转换

import axios from 'axios'
import qs from 'qs'
import { Message, Loading } from 'element-ui'
/**
 * post
 * @param  {String} url -必选   [地址]
 * @param  {Object || Array} params -必选 [参数]
 * @param  {String} type -可选  [设定为 form 为 formdata 提交]
 * @param  { Boolean } isLoading -可选 [是否显示加载状态, 默认显示]
 * @return {Object}        [Promise]
 */
export const $post = (url, params, type, isLoading = true) => {
  if (isLoading) {
    var loadingInstance = Loading.service({
      text: '正在加载中'
    })
  }
  type === 'form' && params = qs.stringify(params)
  return new Promise((resolve, reject) => {
    axios
      .post(url, params, {})
      .then(res => {
        if (isLoading) {
          loadingInstance.close()
        }
        if (res.status === 200) {
          if (res.data.code === 0) {
            resolve(res.data)
          } else if (res.data.code === 401) {
            failMessage(res.data.message)
            setTimeout(() => {
              window.location.href = '/static/login.html'
            }, 2000)
            reject(res)
          } else {
            failMessage(res.data.message)
            reject(res)
          }
        } else {
          failMessage()
          reject(res)
        }
      })
      .catch(mes => {
        if (isLoading) {
          loadingInstance.close()
        }
        if (mes.response.status === 306) {
          failMessage('您身份已过期,3秒后返回登录页面')
          setTimeout(() => {
            window.location.href = '/static/login.html'
          }, 3000)
          reject(mes)
        } else if (mes.response.status === 403) {
          failMessage('无访问权限')
          reject(mes.response.data)
        } else {
          failMessage()
          reject(mes.response.data)
        }
      })
  })
}

function failMessage(mes = '数据获取失败') {
  Message({
    showClose: true,
    message: mes,
    type: 'warning'
  })
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
编辑 (opens new window)
#Vue#axios
上次更新: 5/27/2023, 1:02:05 PM
Vue $attrs 和 $listeners
Vue 开发技巧

← Vue $attrs 和 $listeners Vue 开发技巧→

最近更新
01
version 1.15
07-01
02
version 1.14
06-27
03
version 1.13
06-27
更多文章>
Theme by Vdoing | Copyright © 2017-2023 HenryTSZ | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式