axios请求头设置常见Content-Type和对应封装

1,095 阅读3分钟

Content-Type:

服务器在收到前端的http请求的时候,怎么去解析参数,是请求头header中的Content-Type规定的,也就是内容格式。不同形式的参数设置不同类型的请求头。

比如我们与后端对接时,接口对应请求参数的方式有以下三种: 微信图片_20240131140226.png

axios请求头设置Content-Type常见的数据格式:

  1. Content-Type:application/json:请求体中的数据会以json字符串的形式发送到后端(默认的数据格式)

image.png 2. Content-Type:application/x-www-form-urlencoded:请求体中的数据以表单形式(键值对)发送给后端 将请求体中的数据设置为键值对 (但是求体中的数据一般是JSON对象,这个时候,就可以使用qs库将对象转为url参数形式,也就是将json序列化qs.stringify(),qs是Axios默认就有的,不需要再npm

(注意:不能对请求体中的数据使用扩展运算符...,防止影响到正常解析的分隔)

import qs from 'qs'
var data = {
    "username": "admin",
    "password": "123456"
}
 
axios({
    url: '/OAuth/oauth/token',
    method: 'post',
    headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    // 转为url参数形式
    data: qs.stringify(data)
})
console.log(data);
console.log(qs.stringify(data));

image.png

使用qs之后,都是Form Data image.png 3. Content-Type:multipart/form-data:会把请求体中的数据处理为一条消息,以标签为单元,用分隔符分开。既可以传键值对,也可以传文件,这种方式一般用来上传文件。

项目中封装的axios,后边参考

import axios from 'axios'
import { Promise } from 'es6-promise'
import qs from 'qs'
import conf from '@/config/config'
import { message } from '@/lib/message'

let path = ''

let instance = axios.create({
	timeout: cfg.timeout ? cfg.timeout : 5000,
	baseURL: conf.baseUrl
})

const isDevelop = process.env.NODE_ENV === 'development' ? true : false

const HEADER = { 'Content-Type': 'application/x-www-form-urlencoded' }

const getString = params => {
	return qs.stringify(params)
}

// 添加请求拦截器,在请求头中加token 全局设置请求头
instance.interceptors.request.use(
	config => {
		if (localStorage.getItem('Authorization')) {
			config.headers.Authorization = localStorage.getItem('Authorization')
		}
		return config
	},
	error => {
		return Promise.reject(error)
	}
)

const handleStatus = res => {
	if (res && res.status === 200) {
		// 接口返回状态
		let resStatus = res.data.status
		// 接口提示信息,仅查看数据成功时此项为空字符串,其余结果均需返回提示信息
		let resDescription = res.data.description && res.data.description.length > 0 ? res.data.description.trim() : null
		// 接口返回数据
		let resData = res.data.data
		if (resStatus && resStatus == 'success') {
			if (resDescription) {
				// 有提示信息直接在此处弹出message提示,页面上无需额外提示
				message.success(resDescription)
				// 操作成功如果附带数据则返回数据,无数据则返回true
				return resData ? resData : true
			} else {
				// 查看数据仅返回数据
				return resData
			}
		} else {
			if (resDescription || resData) {
				// 检查是否有提示信息,有则直接在此处全局提示,页面上无需额外处理
				let msg = resDescription ? resDescription : resData
				message.error(`${msg}`)
			} else {
				// 接口error
				// 此处代表后台提示信息不全,没有状态值或提示信息
				if (isDevelop) {
					message.error('数据获取失败。。。')
				}
			}
			return false
		}
	}
}

const handleError = err => {
	// 接口异常信息
	if (err) {
		console.log(err,"err");
		console.log(err.response,"err.description");
		if (err.response.status == 401) {
			localStorage.clear()
			// window.location.href = '/'
			return
		  }
		if (err.description && err.description.length > 0) {
			message.error(err.description)
		} else {
			if (isDevelop) {
				message.error('数据获取失败。。。 。。。')
			}
		}
	}
	return false
}

const handlerHeader = header => {
	let res
	if (typeof header == 'string') {
		if (header == 'form' || header == 'Form') {
			res = { 'Content-Type': 'multipart/form-data' }
		} else if (header == 'json' || header == 'Json') {
			res = { 'Content-Type': 'application/json' }
		}
	} else if (typeof header == 'object') {
		res = header
	} else {
		res = HEADER
	}
	return res
}

//http response拦截器
instance.interceptors.response.use(
	response => {
		return response
	},
	err => {
		if (err && err.response) {
			switch (err.response.status) {
				case 302:
					err.message = '未授权,请重新登录'
					break
				case 400:
					err.message = '错误请求'
					break
				case 401:
					err.message = '未授权,请重新登录'
					break
				case 403:
					err.message = '拒绝访问'
					break
				case 404:
					err.message = '请求错误,未找到该资源'
					break
				case 405:
					err.message = '请求方法未允许'
					break
				case 408:
					err.message = '请求超时'
					break
				case 500:
					err.message = '服务器端出错'
					break
				case 501:
					err.message = '网络未实现'
					break
				case 502:
					err.message = '网络错误'
					break
				case 503:
					err.message = '服务不可用'
					break
				case 504:
					err.message = '网络超时'
					break
				case 505:
					err.message = 'http版本不支持该请求'
					break
				default:
					err.message = `连接错误${err.response.status}`
			}
		} else {
			err.message = '连接服务器失败'
		}
		return Promise.reject(err)
	}
)

export default {
	instance,
	async get(url, params, header) {
		let queryString = []
		let headers = handlerHeader(header)
		if (params) {
			Object.keys(params).forEach(key => params[key] & queryString.push(`${key}=${params[key]}`))
		}
		if (queryString.length > 0) {
			queryString = queryString.join('&')
			url += `?${queryString}`
		}
		try {
			const res = await instance.get(encodeURI(path + url), { headers: headers })
			return handleStatus(res)
		} catch (err) {
			return handleError(err)
		}
	},
	async post(url, params, header) {
		params = header ? params : getString(params)
		let headers = handlerHeader(header)
		try {
			const res = await instance.post(path + url, params, { headers: headers })
			return handleStatus(res)
		} catch (err) {
			return handleError(err)
		}
	},
	async put(url, params, header) {
		params = header ? params : getString(params)
		let headers = handlerHeader(header)
		try {
			const res = await instance.put(path + url, params, { headers: headers })
			return handleStatus(res)
		} catch (err) {
			return handleError(err)
		}
	},
	async delete(url, params) {
		try {
			const res = await instance.delete(path + url, { data: getString(params), headers: HEADER })
			return handleStatus(res)
		} catch (err) {
			return handleError(err)
		}
	}
}

参考网址: blog.csdn.net/weixin_4951… www.cnblogs.com/liangweipin…