玩命加载中🤣🤣🤣

vue_axios


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()

分析

  1. 通过一言接口获取数据,前端进行渲染及展示
  2. 可以发现整体的数据处理使用的是链式编程的方式

解决方式

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

添加核心包

  1. 根目录下新建目录 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"));
  1. 新建目录 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: '无法获取一言数据' }
            }
        }
    }
}
  1. 新增 _config 配置
# custom_api:
custom_api:
  apiDir: 'api'
  allowOrigin: '*'
  enable:
    - 'hitokoto'
  disable_default_api: true
  1. 优化一言调取部分
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',
})

文章作者: 👑Dee👑
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC 4.0 许可协议。转载请注明来源 👑Dee👑 !
  目录