axios-统一用拦截器在header请求头和请求体中添加参数并使用PHP获取

10005次阅读 869人点赞 作者: WuBin 发布时间: 2025-11-14 09:01:11
扫码到手机查看

axios封装和拦截器

axios+拦截器+自定义请求头处理+自定义请求头导致的请求预检处理

axios-统一用拦截器在header请求头和请求体中添加参数并使用PHP获取

axios-关于封装一个底层axios请求和拦截器interceptors,catch错误(throw或reject)?

axios-options请求预检和Vue中axios封装以及withCredentialstrue

axios-abortController、signal配合axios实现一个可以中断请求的操作

/* eslint-disable */
import axios from 'axios'
import { ERR_OK, BASE_URL } from "./config";
import { showAlert } from "@/common/js/sweet-alert";
import { getToken } from "./jwt";

axios.defaults.baseURL = BASE_URL;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8';
// axios向跨域请求携带cookie 必须配合服务端header
axios.defaults.withCredentials = true;


// 请求拦截器:统一添加Token到请求头
axios.interceptors.request.use(
    async (config) => { // 加 async
        const token = getToken();
        if (token) {
            config.headers.Authorization = `Bearer ${token}`;
        }

        const APP_ID = window.setting.app_id;
        // 在请求体中添加固定的参数
        if (config.method === 'get') {
            // GET 请求:添加到 URL 参数
            config.params = {
                app_id: APP_ID,
                // 展开原有的 params,确保不会覆盖
                ...config.params
            };
        }
        else if (['post', 'put', 'patch'].includes(config.method)) {
            // POST 等请求:添加到请求体 区分 FormData 和普通对象
            if (config.data instanceof FormData) {
                // 如果是 FormData,直接追加 app_id
                config.data.append('app_id', APP_ID);
            } else {
                // 普通对象,合并 app_id
                config.data = {
                    app_id: APP_ID,
                    ...config.data
                };
            }
        }
        // 异步函数返回的是 Promise,axios 处理更稳定
        return config;
    },
    (error) => {
        return Promise.reject(error);
    }
);

axios.interceptors.response.use(
    // 在 Axios 的响应拦截器中,成功拦截器必须返回 response(或修改后的 response),否则后续的 .then 会接收到 undefined。
    async (response) => {
        // 这里必须返回response,否则后续.then会拿到undefined
        return response;
    },
    async (error) => {
        // console.log(error.code)
        // 统一处理比如超时等错误
        switch (error.code) {
            case 'ECONNABORTED':
                showAlert({
                    title: '服务器繁忙',
                    text: '请稍候刷新重试',
                    icon: 'error',
                });
                break;
            case 'ERR_NETWORK':
                // 网络错误(比如跨域等)
                showAlert({
                    title: '网络错误',
                    text: '无法连接到服务器,请检查网络设置后,刷新重试',
                    icon: 'error',
                });
                break;
            // 主动中断请求
            case 'ERR_CANCELED':
                console.log('主动中断请求', error.code);
                break;
            default:
                // 处理其他网络错误
                showAlert({
                    title: '服务器繁忙',
                    text: '服务器开小差了,请您稍候再试',
                    icon: 'error',
                });
        }

        return Promise.reject(error);
    }
);

/*
* params 必须是一个对象
* */
export function get(url, params) {
    // 如果不是一个对象就包一下
    if (!(typeof params == 'object')) {
        params = { params }
    }
    return axios.get(url, {
        params: params
    }).then((res) => {
        const serverData = res.data;
        if (serverData.code === ERR_OK) {
            return serverData.data
        } else {
            // 通用的错误处理
            errorHandle(serverData);
            // console.log(serverData.message);
            throw new Error(serverData.msg || '接口请求失败');
        }
    }).catch((e) => {
        console.error(e);
        // 重新抛出错误,让上层调用者处理
        throw e;
        // return null;
    })
}

/*
* params 必须是一个对象
* */
export function post(url, params) {
    if (!(params instanceof FormData) && typeof params !== 'object') {
        params = { params };
    }
    return axios.post(url, params).then((res) => {
        const serverData = res.data;
        if (serverData.code === ERR_OK) {
            return serverData.data;
        } else {
            errorHandle(serverData);
            throw new Error(serverData.msg || '接口请求失败');
        }
    }).catch((e) => {
        console.error('post请求错误:', e);
        throw e;
        // return null;
    });
}

// upload方法(专门处理文件上传,独立配置)
export function upload(url, formData) {
    // 校验参数:确保传递的是FormData(避免传错格式)
    if (!(formData instanceof FormData)) {
        console.error('upload方法仅支持FormData参数!');
        throw new Error('参数格式错误,需传递FormData');
        // return Promise.reject(new Error('参数格式错误,需传递FormData'));
    }

    // 独立请求配置:覆盖默认头,确保文件格式正确
    const requestConfig = {
        headers: {
            // 关键:设置为multipart/form-data(axios也会自动识别FormData并生成,这里显式设置更保险)
            'Content-Type': 'multipart/form-data'
        }
    };

    // 发送文件上传请求
    return axios.post(url, formData, requestConfig).then((res) => {
        // console.log(res)
        const serverData = res.data;
        // console.log(serverData)
        if (serverData.code === ERR_OK) {
            return serverData.data; // 返回后端的文件URL等数据
        } else {
            errorHandle(serverData);
            console.log('文件上传失败:', serverData);
            throw new Error(serverData.msg || '接口请求失败');
        }
    }).catch((e) => {
        console.log('图片上传失败:', e);
        throw new Error('图片上传失败,请稍候重试');
    });
}

function errorHandle(serverData) {
    switch (serverData.code) {
        // 1000是登录方面的问题
        case 1000:
            window.alert(serverData.msg);
            window.location.href = serverData.data.login;
            break;
        // 400是上传图片问题
        case 400:
            showAlert({
                text: serverData.msg
            });
            break;
        default:
            showAlert({
                text: serverData.msg
            });
    }
}

以上是我在全局axios下,对axios进行的封装,里面包含了拦截器、基础的post\get、上传请求,并且在拦截器中统一添加了携带token的自定义请求头Header以及在请求体中添加了统一的app_id参数,这样就不需要每次在方法中单独设置app_id这个参数了。

注意,upload传进来的必须是一个formdata对象
<input
        type="file"
        ref="fileInput"
        accept="image/png,image/jpg,image/jpeg"
        @change="handleFileChange"
        class="file-input"
>
handleFileChange(e) {
    const file = e.target.files[0];
    const formData = new FormData();
    formData.append('image', file);
    upload('urlxxx', formData)
},
在拦截器中也是通过检测是不是formdata,如果是,那么就需要使用formData.append来添加参数。

当然,以上axios封装是基于全局的(还可以创建单独的axios实例,避免全局污染),而且还可以在get\post等方法中,添加第三个config参数,通过用 AbortController 包装请求,还可以实现主动中断请求的操作。

参考:https://www.wubin.work/blog/articles/613

当然因为发送了自定义请求头,所以后端会触发请求预检,后端也需要添加修改。

参考:https://www.wubin.work/blog/articles/615

PHP处理请求预检

axios中的withCredentials: true不能单独使用,否则会触发跨域错误,需要后端配合设置两个关键响应头:

  • Access-Control-Allow-Credentials: true告诉浏览器:「允许这个跨域请求携带凭证」。

  • Access-Control-Allow-Origin: 具体域名(如http://localhost:8081必须指定明确的前端域名,不能用 *(浏览器规定:带凭证的跨域请求不允许 Origin 为 *)。

所以当有自定义Header的时候PHP需要添加白名单机制:

<?php
header("content-type:application/json;charset=utf-8");

// 定义允许的前端域名白名单(数组形式,末尾无斜杠)
$allowedOrigins = [
    'http://192.168.1.101:8080',
    'http://localhost:8080',
    'https://yourdomain.com' // 可添加更多域名
];

try{
	// 动态获取前端请求源(可能为空,如非跨域请求)
	/*
    *  比如项目地址:https://ai2hinen9t1.thexin.cn/ai/article-chufa/
    *  $_SERVER['HTTP_ORIGIN']得到的就是https://ai2hinen9t1.thexin.cn
    *  所以白名单只需要添加https://ai2hinen9t1.thexin.cn 这个域名即可
    */
    $origin = $_SERVER['HTTP_ORIGIN'] ?? '';

    // 判断当前请求源是否在白名单中
    $isAllowed = in_array($origin, $allowedOrigins);

    // 1. 处理 OPTIONS 预检请求 不要执行业务逻辑
    if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
        if ($isAllowed) {
            header("Access-Control-Allow-Origin: {$origin}"); // 返回当前请求的域名
            header("Access-Control-Allow-Headers: Authorization, Content-Type");
            header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
            header("Access-Control-Allow-Credentials: true");
            // Access-Control-Max-Age 让浏览器缓存预检结果,减少 OPTIONS 请求次数,提升性能
            header("Access-Control-Max-Age: 86400"); // 缓存预检结果24小时
        }
        exit;
    }

    // 2. 处理实际请求(POST/GET)
    if ($isAllowed) {
        header("Access-Control-Allow-Origin: {$origin}"); // 返回当前请求的域名
        header("Access-Control-Allow-Credentials: true");
    } else {
        // 直接抛错,进入catch统一处理
    	throw new Exception('当前请求不在白名单中,请与管理员联系', 1003);
    }

    // 假设原有业务逻辑
    $log = "{$_SERVER['REQUEST_METHOD']} " . date('Y-m-d H:i:s') . "\n";
    $filename = __DIR__. '/debuglog/' . uniqid() . '_debug.log';
    $filecontent = $log . print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)
    file_put_contents($filename, $filecontent, true) . "\n\n", FILE_APPEND);
	
} catch (Exception $e) {
	// 直接给错误状态
    http_response_code(401);
    // 获取错误码和错误信息
    $errcode = $e->getCode();
    $errmsg = $e->getMessage();
    
    exit(输出json等)
}

?>

在白名单检查那里,$_SERVER['HTTP_ORIGIN']当是同源请求(x1/a.html get访问 x1/server/xxx.php)、从浏览器直接访问url地址、服务端之间的CURL请求的时候,都会是空!所以需要额外加一个判断,只有有值的时候,才去检测来源,如果没有那么就默认它是来自同源的请求!然后服务端之间不要依赖origin!要用额外的自定义api_key去核实!

$allowedOrigins = [
        'https://ai2hinen9t1.thexin.cn'
    ];

    // 动态获取前端请求源(可能为空,如非跨域请求)
    $origin = $_SERVER['HTTP_ORIGIN'] ?? '';
    
    // 如果是空 代表是一个同源的请求 不处理
    if(empty($origin)) {
        $isAllowed = true;
    } else {
        // 判断当前请求源是否在白名单中
        $isAllowed = in_array($origin, $allowedOrigins);
    }

PHP获取自定义请求头的内容

在 PHP 中获取 HTTP 请求头(Header)中的Authorization信息(也就是你说的 Token)有两种常用方法:

方法一:使用$_SERVER超全局变量(最常用)

PHP 会将大部分请求头转换为$_SERVER数组中的元素,格式通常是HTTP_前缀加上大写的 header 名称,并用下划线_替换横杠-

对于Authorization: Bearer 12345567888这个 header,你可以这样获取:

<?php
// 从 $_SERVER 数组中获取 Authorization header
$authorizationHeader = $_SERVER['HTTP_AUTHORIZATION'];

// 检查 header 是否存在
if (!isset($authorizationHeader)) {
    // 如果不存在,返回 401 Unauthorized 错误
    http_response_code(401);
    echo json_encode(['error' => 'Authorization header is missing']);
    exit;
}

// 检查 header 是否以 'Bearer ' 开头
$token = null;
$pattern = '/^Bearer\s+(.*)$/i'; // 正则表达式,不区分大小写
if (preg_match($pattern, $authorizationHeader, $matches)) {
    $token = trim($matches[1]);
}

if ($token === null) {
    // 如果 Token 格式不正确
    http_response_code(401);
    echo json_encode(['error' => 'Invalid token format']);
    exit;
}

// 在这里使用你的 token
echo "成功获取到 Token: " . $token;
// 例如:12345567888

?>

方法二:使用getallheaders()函数(推荐在 PHP-FPM 等现代环境中使用)

getallheaders()函数会返回一个包含所有 HTTP 请求头的关联数组。这个方法的代码看起来更直观。

<?php
// 获取所有请求头
$headers = getallheaders();

// 检查 'Authorization' header 是否存在
if (!isset($headers['Authorization'])) {
    http_response_code(401);
    echo json_encode(['error' => 'Authorization header is missing']);
    exit;
}

$authorizationHeader = $headers['Authorization'];

// 同样使用正则表达式提取 Token
$token = null;
$pattern = '/^Bearer\s+(.*)$/i';
if (preg_match($pattern, $authorizationHeader, $matches)) {
    $token = trim($matches[1]);
}

if ($token === null) {
    http_response_code(401);
    echo json_encode(['error' => 'Invalid token format']);
    exit;
}

// 在这里使用你的 token
echo "成功获取到 Token: " . $token;
// 例如:12345567888

?>

两个方法的对比

特性$_SERVER['HTTP_AUTHORIZATION']getallheaders()
兼容性非常好,兼容所有 PHP 版本和服务器环境(如 Apache, Nginx + PHP-FPM)。在 Apache 下表现良好。在 Nginx + PHP-FPM 环境中,需要确保fastcgi_param AUTHORIZATION $http_authorization;已配置,否则可能获取不到。
代码简洁性稍长,需要手动构造键名。更简洁、直观,直接通过原始 header 名称获取。

推荐优先使用方法一($_SERVER['HTTP_AUTHORIZATION'])。

$_SERVER['HTTP_AUTHORIZATION']和getallheaders()返回是Null的问题

如果$_SERVER['HTTP_AUTHORIZATION']和getallheaders()返回的都是Null,那么这是因为服务器(如 Apache)默认不会将Authorization头传递给 PHP,需要通过配置显式开启。

出于安全和协议规范的考虑,Apache 等服务器默认会过滤Authorization头,不会将其暴露给 PHP 的$_SERVER变量。只有显式配置后,才能通过$_SERVER['HTTP_AUTHORIZATION']获取到该头信息。

Apache环境(局部配置):

在项目根目录的.htaccess文件中添加以下配置:

# 方法一:通过 SetEnvIf 传递 Authorization 头
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

# 方法二:通过 mod_rewrite 传递(需确保已启用 mod_rewrite)
RewriteEngine On
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

添加后重启 Apache 服务,即可通过$_SERVER['HTTP_AUTHORIZATION']正常获取 Token。

如果修改重启后还未生效,可能是 Apache 未启用mod_rewritemod_setenvif模块,在httpd.conf中:

# 启用 mod_setenvif(方法一依赖)
LoadModule setenvif_module modules/mod_setenvif.so

# 启用 mod_rewrite(方法二依赖,若用方法二需开启)
LoadModule rewrite_module modules/mod_rewrite.so

还需要允许.htaccess生效:

httpd.conf中搜索`(或你项目所在的目录配置),确保以下参数为All`:

<Directory "${INSTALL_DIR}/htdocs">
    Options Indexes FollowSymLinks Includes ExecCGI
    AllowOverride All  # 必须设为 All,允许 .htaccess 生效
    Require local
</Directory>

Apache环境(全局配置)

全局开启后,本地 Apache 所有项目都能直接获取Authorization头,无需每个项目单独配置.htaccess,核心是修改 Apache 主配置文件(我本地是phpstudy,找到http.conf文件):

添加全局传递规则

httpd.conf文件末尾(推荐方法一):

# 方法一:全局传递 Authorization 头(优先选,无需启用重写模块)
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

# 方法二:若需用重写模块传递(已启用 mod_rewrite 时可用)
# RewriteEngine On
# RewriteCond %{HTTP:Authorization} .
# RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

文件内搜索mod_setenvif.so,必须确保mod_setenvif.so行处于解开注释的状态

# 启用 mod_setenvif(方法一必须开启)
LoadModule setenvif_module modules/mod_setenvif.so

# 若用方法二,需启用 mod_rewrite
# LoadModule rewrite_module modules/mod_rewrite.so

修改好之后,记得重启apache服务器

Nginx环境(未测试,仅记录):

如果使用 Nginx + PHP-FPM,需要在 Nginx 配置文件中显式传递Authorization头:

location ~ \.php$ {
    # 其他配置...
    fastcgi_param AUTHORIZATION $http_authorization;
}

如何验证当前服务器设置是否能正常使用getallheaders()$_SERVER['HTTP_AUTHORIZATION']

作为开发者,有时候也不知道服务器当前的设置是否支持getallheaders()和$_SERVER['HTTP_AUTHORIZATION'],我们该如何进行验证?很简单,做一个简单的请求即可:

前端HTML

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>jQuery Header 请求测试</title>
    <!-- 引入 jQuery(使用 CDN) -->
    <!-- <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.min.js"></script> -->
    <script src="https://www.qdxin.cn/js/xinquery.js"></script>
</head>
<body>
    <h1>测试 jQuery 发送 Header 请求</h1>
    <button id="sendRequest">发送请求</button>
    <div id="result"></div>

    <script>
        $(function() {
            $('#sendRequest').click(function() {
                // 发起 POST 请求
                $.ajax({
                    url: 'test-1.php', // 目标 PHP 文件
                    type: 'POST',      // 请求方法(GET/POST 均可)
                    headers: {
                        // 自定义 Header(重点)
                        'Authorization': 'Bearer 123456789', // Token 示例
                        'X-Custom-Header': 'Test-Value'      // 自定义其他 Header
                    },
                    data: {
                        username: 'test',
                        age: 20
                    },
                    success: function(response) {
                        // 请求成功后的处理
                        $('#result').html(`
                            <h3>请求成功!</h3>
                            <pre>${JSON.stringify(response, null, 2)}</pre>
                        `);
                    },
                    error: function(xhr, status, error) {
                        // 请求失败后的处理
                        $('#result').html(`
                            <h3>请求失败!</h3>
                            <p>状态码:${xhr.status}</p>
                            <p>错误信息:${error}</p>
                        </pre>
                        `);
                    }
                });
            });
        });
    </script>
</body>
</html>

后端PHP,test-1.php

<?php
// 输出 $_SERVER['HTTP_AUTHORIZATION'] 的值
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '未获取到';
echo "HTTP_AUTHORIZATION 的值:" . $authHeader . "\n";

// 同时输出 getallheaders() 的结果(用于对比)
if (function_exists('getallheaders')) {
    $headers = getallheaders();
    $authFromHeaders = isset($headers['Authorization']) ? $headers['Authorization'] : '未获取到';
    echo "通过 getallheaders() 获取的 Authorization 头:" . $authFromHeaders . "\n";
} else {
    echo "服务器不支持 getallheaders() 函数\n";
}

简单测试服务器是否支持getallheaders函数:

<?php
if (function_exists('getallheaders')) {
    echo "服务器支持 getallheaders() 函数";
} else {
    echo "服务器不支持 getallheaders() 函数";
}
?>

更加完善的测试代码(仅做记录,使用第一段代码足够):

<?php
// 设置响应为 JSON 格式
header("Content-Type: application/json; charset=utf-8");

// 允许跨域(如果前端和后端不在同一域名下)
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Authorization, X-Custom-Header, Content-Type");

// 收集所有请求头信息
$headers = [];
if (function_exists('getallheaders')) {
    $headers = getallheaders();
} else {
    // 兼容不支持 getallheaders() 的环境
    foreach ($_SERVER as $name => $value) {
        if (substr($name, 0, 5) == 'HTTP_') {
            $headers[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))))] = $value;
        }
    }
}

// 构造返回数据
$response = [
    'status' => 'success',
    'received_headers' => $headers,
    'received_data' => $_POST, // 接收 POST 数据
    'server_auth_header' => $_SERVER['HTTP_AUTHORIZATION'] ?? '未获取到'
];

// 返回 JSON 数据
echo json_encode($response, JSON_UNESCAPED_UNICODE);
?>

PHP完整获取自定义请求头和请求体+域名白名单

注意,这里如果确定$origin = $_SERVER['HTTP_ORIGIN'] ?? ''; 此脚本只是通过浏览器进行访问,那么这么写没问题,一旦有服务器->服务器的curl通信,那么就需要注意,需要对服务器curl发起的请求,添加origin,如下:

$ch = curl_init();
$options = array(
    CURLOPT_URL => $url,
    CURLOPT_POST => true, 
    CURLOPT_RETURNTRANSFER => true, 
    CURLOPT_FOLLOWLOCATION => true,
    CURLOPT_HEADER => false,
    CURLOPT_POSTFIELDS => http_build_query($params),
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/x-www-form-urlencoded',
        // 手动添加 Origin 头,值可以是你允许的任何一个白名单域名
        'Origin: https://ai2hinen9t1.thexin.cn' 
    ]
);
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
if(curl_error($ch)) {
    $errMsg = 'Error: ' . curl_error($ch);
    curl_close($ch);
    return false;
}
 curl_close($ch);

如果不加,那么服务端->服务端的通信,$_SERVER['HTTP_ORIGIN']就只会返回空值。这一点要特别注意。

<?php
try {

    // 定义允许的前端域名白名单(数组形式,末尾无斜杠)
    /**
     *  比如项目地址:https://ai2hinen9t1.thexin.cn/ai/article-chufa/
     *  $_SERVER['HTTP_ORIGIN']得到的就是https://ai2hinen9t1.thexin.cn
     *  所以白名单只需要添加https://ai2hinen9t1.thexin.cn 这个域名即可
     */
    $allowedOrigins = [
        'http://192.168.1.101:8080'
    ];

    // 动态获取前端请求源(可能为空,如非跨域请求)
    $origin = $_SERVER['HTTP_ORIGIN'] ?? '';

    // 判断当前请求源是否在白名单中
    $isAllowed = in_array($origin, $allowedOrigins);

    // 处理 OPTIONS 预检请求
    if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
        if ($isAllowed) {
            header("Access-Control-Allow-Origin: {$origin}"); // 返回当前请求的域名
            header("Access-Control-Allow-Headers: Authorization, Content-Type");
            header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
            header("Access-Control-Allow-Credentials: true");
            header("Access-Control-Max-Age: 86400"); // 缓存预检结果24小时
        }
        exit;
    }

    // 处理实际请求(POST/GET)
    if ($isAllowed) {
        header("Access-Control-Allow-Origin: {$origin}"); // 返回当前请求的域名
        header("Access-Control-Allow-Credentials: true");
    } else {
        throw new Exception('当前请求不在白名单中,请与管理员联系', 1003);
    }

    # 验证用户权限
    // 从 $_SERVER 数组中获取 Authorization header 这个依赖服务器配置
    $authorizationHeader = $_SERVER['HTTP_AUTHORIZATION'];
    // 检查 header 是否存在
    if (!isset($authorizationHeader)) {
       throw new Exception('header不存在', 1003);
    }

    // 检查 header 是否以 'Bearer ' 开头
    $token = null;
    // 正则表达式,不区分大小写
    $pattern = '/^Bearer\s+(.*)$/i';
    if (preg_match($pattern, $authorizationHeader, $matches)) {
        $token = trim($matches[1]);
    }
    if ($token === null) {
        // 如果 Token 格式不正确
        throw new Exception('Invalid token format', 1003);
    }

    // 获取前端拦截器统一添加的app_id
    $appid = $_REQUEST['app_id'] ?? '';
    if(!$appid) {
        throw new Exception('appid is wrong', 1003);
    }
} catch(Exception $e) {
    // 直接给401状态
    http_response_code(401);

    $errcode = $e->getCode();
    $errmsg = $e->getMessage();

    $json = json_encode([
        'code'  => $errcode,
        'msg'   => $errmsg,
        'data'  => []
    ], JSON_UNESCAPED_UNICODE);
    exit($json);
}
点赞 支持一下 觉得不错?客官您就稍微鼓励一下吧!
关键词:axios,getallheaders,自定义请求头,拦截器,获取请求头
推荐阅读
  • python基础-操作列表和迭代器

    python基础笔记-操作列表和迭代器的相关方法

    6708次阅读 164人点赞 发布时间: 2024-06-13 13:26:27 立即查看
  • uniapp实现被浏览器唤起的功能

    当用户打开h5链接时候,点击打开app若用户在已经安装过app的情况下直接打开app,若未安装过跳到应用市场下载安装这个功能在实现上主要分为两种场景,从普通浏览器唤醒以及从微信唤醒。

    12221次阅读 828人点赞 发布时间: 2022-12-14 16:34:53 立即查看
  • PHP

    【正则】一些常用的正则表达式总结

    在日常开发中,正则表达式是非常有用的,正则表达式在每个语言中都是可以使用的,他就跟JSON一样,是通用的。了解一些常用的正则表达式,能大大提高你的工作效率。

    15425次阅读 646人点赞 发布时间: 2021-10-09 15:58:58 立即查看
  • 【中文】免费可商用字体下载与考证

    65款免费、可商用、无任何限制中文字体打包下载,这些字体都是经过长期验证,经得住市场考验的,让您规避被无良厂商起诉的风险。

    16367次阅读 1304人点赞 发布时间: 2021-07-05 15:28:45 立即查看
  • Vue

    Vue3开发一个v-loading的自定义指令

    在vue3中实现一个自定义的指令,有助于我们简化开发,简化复用,通过一个指令的调用即可实现一些可高度复用的交互。

    18720次阅读 1503人点赞 发布时间: 2021-07-02 15:58:35 立即查看
  • JS

    关于手机上滚动穿透问题的解决

    当页面出现浮层的时候,滑动浮层的内容,正常情况下预期应该是浮层下边的内容不会滚动;然而事实并非如此。在PC上使用css即可解决,但是在手机端,情况就变的比较复杂,就需要禁止触摸事件才可以。

    16901次阅读 1366人点赞 发布时间: 2021-05-31 09:25:50 立即查看
  • Vue

    Vue+html2canvas截图空白的问题

    在使用vue做信网单页专题时,有海报生成的功能,这里推荐2个插件:一个是html2canvas,构造好DOM然后转canvas进行截图;另外使用vue-canvas-poster(这个截止到2021年3月...

    32715次阅读 2567人点赞 发布时间: 2021-03-02 09:04:51 立即查看
  • Vue

    vue-router4过度动画无效解决方案

    在初次使用vue3+vue-router4时候,先后遇到了过度动画transition进入和退出分别无效的情况,搜遍百度没没找到合适解决方法,包括vue-route4有一些API都进行了变化,以前的一些操...

    28566次阅读 2199人点赞 发布时间: 2021-02-23 13:37:20 立即查看
交流 收藏 目录