Axios请求示例
本篇基于vue2, 简单自定义拦截器, 并发送post请求至后端服务器
1. 安装
npm install axios -S
2. 拦截器配置示例
import axios from "axios"
// 创建axios
const _axios = axios.create({
baseURL: "http://localhost:23323"
})
_axios.interceptors.request.use(
config => {
// 设置token请求头
config.headers = {
Authorization: '222.333.zzZ'
}
return config
},error => {
return Promise.reject(error)
}
)
_axios.interceptors.response.use(
rep => {
// 2xx范围走这里
return rep
}, error => {
if (error.response === undefined){
return Promise.reject(error);
}
// 超出2xx走这里, 示例列举
let status = error.response.status
if (status === 400){
window.alert('请求参数错误')
return Promise.resolve(400)
} else if (status === 404){
window.alert('资源不存在');
return Promise.resolve(404)
} else if (status === 405) {
window.alert('请求方式错误')
return Promise.resolve(405)
}
return Promise.reject(error)
}
)
export default _axios
3. axios使用(POST示例)
3.1 URL拼接参数
async sendPostWithUrl() {
// 此处注意,需要进行编码
let name = encodeURIComponent('dee+')
let age = 18
const resp = await axios.post(`/uri?name=${name}&age=${age}`)
console.log(resp)
}
Request URL: http://ip:port/uri?name=dee%2B&age=18 (会自动进行unicode编码)
Response Headers: 中无 Content-Type
3.2 将参数对象放入config
async sendPostWithConfig() {
const resp = await _axios.post(`/uri`, null, {
params: {
name: 'dee+',
age: 20
}
})
console.log(resp)
}
Request URL: http://ip:port/uri?name=dee%2B&age=20 (会自动进行unicode编码)
Response Headers :
Content-Type: application/x-www-form-urlencoded
3.3 先urlencode编码, 再通过data参数发送请求
async sendPostWithUrlEncoded() {
let stu = new URLSearchParams()
stu.append('name', 'dee+')
stu.append('age', 38)
const resp = await _axios.post(`/uri`, stu)
console.log(resp)
}
Request URL: http://ip:port/uri
Response Headers :
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
3.4 form-data格式请求
async sendPostWithFormdata() {
let stu = new FormData()
stu.append("name", 'dee+')
stu.append("age", 38)
const resp = await _axios.post(`/uri`, stu)
console.log(resp)
}
Request URL
: http://ip:port/uri
Response Headers :
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryvOzpiDlfBzqdp23l
3.5 json格式请求
async sendWithJson() {
let stu = {
name: 'dee+',
age: 30
}
const resp = await axios.post(`/uri`, stu)
console.log(resp);
}
Request URL: http://ip:port/uri
Response Headers :
Content-Type: application/json
记一次一言请求优化
分析与解决
源代码无法调取一言接口,后续进行优化
var hitokotoContent = ''
function typed(hitokotoContent) {
var typed = new Typed("#hitokoto", {
strings: [
hitokotoContent
],
startDelay: <%= theme.hitokoto.startDelay %>,
typeSpeed: <%= theme.hitokoto.typeSpeed %>,
loop: <%= theme.hitokoto.loop %>,
backSpeed: <%= theme.hitokoto.backSpeed %>,
showCursor: <%= theme.hitokoto.showCursor %>
});
}
async function hitokoto() {
try {
}
hitokotoContent = await fetch('https://v1.hitokoto.cn', {
method: 'GET',
})
.then(function (res) {
if (!res) {
console.log('一言没有响应数据')
return null
}
return res.json();
})
.then(function (data) {
if (!data) {
return null
}
return (
`<span>『${data.hitokoto}』<span/><br/>` +
`<span style="text-align: end; font-size: smaller"> ——「${data.from}」<span/>`
);
})
.catch(function (err) {
console.error(err);
})
if (!hitokotoContent) {
console.log('hitokotoContent', hitokotoContent)
await typed(hitokotoContent)
}
}
hitokoto()
分析
- 通过一言接口获取数据,前端进行渲染及展示
- 可以发现整体的数据处理使用的是链式编程的方式
解决方式
async function fetchHitokoto() {
try {
const response = await fetch('https://v1.hitokoto.cn', {
method: 'GET',
// 不需要设置 mode 为 no-cors,因为那样会限制我们访问响应数据
// 同时,也不需要设置以下 headers,除非服务器明确要求
// headers: {
// accept: "application/json",
// "content-type": "application/json"
// }
})
if (!response.ok) {
console.log('一言请求失败');
return null
}
const data = await response.json();
if (!data || !data.hitokoto) {
console.log('一言返回的数据格式不正确')
return null
}
return (
`<span>『${data.hitokoto}』</span><br/>` +
`<span style="text-align: end; font-size: smaller">——「${data.from || '未知来源'}」</span>`
)
} catch (error) {
console.error('一言请求出错:', error)
return null
}
}
function initTyped(hitokotoContent) {
if (hitokotoContent) {
new Typed("#hitokoto", {
strings: [hitokotoContent],
startDelay: <%= theme.hitokoto.startDelay %>,
typeSpeed: <%= theme.hitokoto.typeSpeed %>,
loop: <%= theme.hitokoto.loop %>,
backSpeed: <%= theme.hitokoto.backSpeed %>,
showCursor: <%= theme.hitokoto.showCursor %>
})
} else {
console.log('没有获取到一言内容')
}
}
async function loadHitokoto() {
const hitokotoContent = await fetchHitokoto()
initTyped(hitokotoContent)
}
// 确保 DOM 已经完全加载后再调用 loadHitokoto
document.addEventListener('DOMContentLoaded', loadHitokoto)
跨域问题解决
由于 hexo-info-api 无法加载自定义配置的api,因此参考其源码自行实现
必要依赖安装
npm i body-parser --save
# 同时安装axios
npm i axios --save
添加核心包
- 根目录下新建目录
scripts/custom
,并且新增文件index.js
'use strict';
const fs = require('hexo-fs');
const path = require('path');
const bodyParser = require('body-parser');
// 从_config.yml中读取自定义配置
hexo.config.custom_api = Object.assign({
apiDir: '', // 自定义API目录
allowOrigin: "",
enable: [], // 启用的API列表
disable_default_api: false,
}, hexo.config.custom_api || {});
hexo.log.info(`custom-api: 加载yaml配置 = ${JSON.stringify(hexo.config.custom_api)}`)
// 设置响应头与跨域
function setHeader(req, res, next){
res.setHeader('Access-Control-Allow-Origin', hexo.config.custom_api.allowOrigin);
res.setHeader('Access-Control-Allow-Credentials', 'true');
res.setHeader('Content-Type', 'application/json; charset=utf-8');
next();
}
hexo.extend.filter.register('server_middleware', function(app){
app.use(hexo.config.root + 'api/', setHeader);
app.use(hexo.config.root + 'api/', bodyParser.json({
limit: '50mb'
}));
}, 1);
// 动态加载自定义API
if (Array.isArray(hexo.config.custom_api.enable)) {
hexo.config.custom_api.enable.forEach(api => {
hexo.log.info('当前目录 >>> __driname', __dirname) // D:\dee_code\dee-blog-code\scripts\custom
const apiPath = path.join(__dirname, hexo.config.custom_api.apiDir, `${api}.js`);
hexo.log.info(`custom-api: 加载api [${api}] 目标路径: [${apiPath}]`);
if (fs.existsSync(apiPath)) {
let apiMethod = require(apiPath);
hexo.extend.generator.register(`api.${api}`, function(){
return apiMethod(hexo);
});
hexo.log.info(`custom-api: [${api}] api 可用`);
} else {
hexo.log.warn(`custom-api: api [${api}] 没有找到 [${apiPath}]. 检查js配置文件.`);
}
});
}
// 如果没有禁用默认接口,则注册它
if (!hexo.config.custom_api.disable_default_api)
hexo.extend.generator.register("api", require("./lib/api/default"));
- 新建目录
scripts/custom/api
,并且新增文件hitokoto.js
/* hexo-info-api API module */
const axios = require('axios')
'use strict';
// 定义自定义 API 路由
module.exports = function (hexo) {
return {
path: 'api/hitokoto/', // 定义 API 路径
data: async function () {
try {
const response = await axios.get('https://v1.hitokoto.cn/')
return response.data
} catch (error) {
console.error('一言请求出错:', error)
return { error: '无法获取一言数据' }
}
}
}
}
- 新增
_config
配置
# custom_api:
custom_api:
apiDir: 'api'
allowOrigin: '*'
enable:
- 'hitokoto'
disable_default_api: true
- 优化一言调取部分
const response = await fetch('https://v1.hitokoto.cn', {
method: 'GET',
// 不需要设置 mode 为 no-cors,因为那样会限制我们访问响应数据
// 同时,也不需要设置以下 headers,除非服务器明确要求
// headers: {
// accept: "application/json",
// "content-type": "application/json"
// }
})
// 把上面部分替换成下面部分
const response = await fetch('/api/hitokoto', {
method: 'GET',
})