Вторичная упаковка Аксиос

axios

axios — это http-библиотека на основе Promise, которую можно использовать в браузерах и node.js. В то же время это также инкапсуляция собственного запроса браузера XMLHttpRequest, поддерживает запрос APi Promise, позволяет избежать проблемы возврата в ад, может перехватывать запрос, изменять параметры запроса перед отправкой запроса и принимать сервер Код обрабатывается единообразно, и клиент поддерживает защиту XSRF. Его можно использовать «из коробки», но в реальном проекте аксиомы нужно упаковывать дважды.

Экземпляр или значения по умолчанию

Существует два способа дважды инкапсулировать axios: один — создать экземпляр axios, а другой — напрямую изменить значения по умолчанию для axios.

import axios from 'axios';
var instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});
import axios from 'axios';
axios.defaults.baseURL = SERVICE;

Конечно, при использовании первого метода для создания экземпляра вы также можете установить значения по умолчанию для этого экземпляра, например

import axios from 'axios';
var instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});
instance.defaults.baseURL = SERVICE;

установить базовый URL-адрес

При разделении проектов от начала до конца часто необходимо определить глобальную переменную для объявления адреса интерфейса бэкэнда.Как правило, я выбираю установку глобальных переменных для страницы через плагин definePlugin веб-пакета и передаю разные значения в соответствии с различными средами. Например, фоновый интерфейс развернут вhttp://localhost:3000Затем сначала используйте webpack, чтобы определить глобальную переменную с именем SERVICE.

new webpack.DefinePlugin({
    SERVICE: "'http://localhost:3000'"
})

Затем вы можете использовать эту глобальную переменную на странице.Конечно, если она находится в рамках проекта ts, использование SERVICE напрямую приведет к неопределенной ошибке, поэтому вам нужно только объявить ее в файле, который использует SERVICE.Вы можете использовать ts без Пропустите это утверждение.

import axios from 'axios';
// ts 下使用 需要先声明
declare const SERVICE: string;
axios.defaults.baseURL = SERVICE;

Установить тип контента

В запросе публикации и запросе размещения вам необходимо установить тип контента в заголовке запроса на application/x-www-form-urlencoded.

axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.headers.put['Content-Type'] = 'application/x-www-form-urlencoded';

установить с учетными данными

При выполнении междоменного запроса файлы cookie по умолчанию не переносятся, что приводит к странице входа в проекты разделения внешнего и внутреннего интерфейса, а затем происходит переход на главную страницу после входа в систему, но интерфейс, запрошенный в Главная страница не обнаруживает, что у пользователя есть После входа в систему он вернется на страницу входа, что, вероятно, так и есть. Тогда причина в том, что axios не переносит файлы cookie при инициировании запроса, что можно решить, установив для withCredentials значение true.

axios.defaults.withCredentials = true;

обработка запросов на перехват запросов

Перехватывая запросы, изменяя параметры и сериализуя параметры, можно предотвратить атаки XSRF. сериализовать с помощьюqsреализовать,qsПреимущество может быть сделано из последовательности сложных типов, таких как глубокий массив JSON.

axios.interceptors.request.use((config: any): any => {
    // 给请求添加请求时间
    if (config.url.indexOf('?') !== -1) {
        config.url += `&t=${new Date().getTime()}`;
    } else {
        config.url += `?t=${new Date().getTime()}`;
    }
    // `transformRequest` 允许在向服务器发送前,修改请求数据
    // 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
    // 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
    config.transformRequest = [(data: any, headers: any) => {
        return qs.stringify(data, {
            allowDots: true
        })
    }];
    // `paramsSerializer` 是一个负责 `params` 序列化的函数
    config.paramsSerializer = (params: any) => {
        return qs.stringify(params, {
            arrayFormat: 'repeat'
        })
    };
    return config;
}, (error: any) => {
    return Promise.reject(error);
});

Обработать ответ

Есть такой сценарий, когда код, возвращаемый интерфейсом, равен 2, это говорит о том, что пользователь не вошел в систему. из одного запроса и одного запроса, безусловно, будет очень хлопотно. Какой запрос забыт? Если вы добавите суждение, он будет завершен, поэтому axios предоставляет операцию по перехвату ответа.

axios.interceptors.response.use((response: any): any => {
    const { data } = response;
    if(data.code === 2){
        window.location.href = `/login?from=${window.location.pathname}`;
    }
    return response;
}, (error: any) => {
    Promise.reject(error);
});

общая операция axios

ПОЛУЧИТЬ запрос

get запросы, для запросов на получение, которые требуют параметров, не забудьте указать параметры в параметрах, иначе вы пострадаете. Сценарий использования таков, для получения id почты, mailId - это очень длинная строка различных символов, в которой бывает что-то или \ или: или что-то в этом роде, специфики не знаю, конечная причина mailID этого почтового ящика не может пройти через фон, потому что проблематично разместить этот параметр сразу за маршрутом, поэтому, пожалуйста, поместите параметр прямо в params, потому что параметры в params были обработаны выше.

axios.get('/api/info',{
    params: {
        id: 1
    }
}).then(res => {

}).catch(err => {

})

Опубликовать запрос

axios.post('/api/info',{
    username: 'haha',
    password: '123456'
}).then(res => {

}).catch(err => {

})

Удалить запрос похож на получение запроса на запрос похоже на запись запроса

цепной вызов

axios.get('/api/info',{
    params: {
        id: 1
    }
}).then(res => {
    return axios.post('/api/info',{
        username: 'haha',
        password: '123456'
    });
}).then(res => {

}).catch(err => {

})

axios.all

а такжеPromise.allТочно так же он используется для одновременной обработки нескольких запросов. Обратный вызов выполняется, когда все запросы выполнены, а параметр обратного вызова представляет собой массив. Порядок в массиве соответствует порядку запросов, то есть , он сохраняет возвращаемое значение по порядку.

axios.all([
    axios.get('/api/info',{
        params: {
            id: 1
        }
    }),
    axios.post('/api/info',{
        username: 'haha',
        password: '123456'
    });
]).then(resArray => {
    // resArray[0] 为axios.get('/api/info') 的res
    // resArray[1] 为axios.post('/api/info') 的res
}).catch(err => {

})

Полный код — модульная разработка

После инкапсуляции экспортируйте аксиомы, и другие страницы могут напрямую ссылаться на аксиомы. Полный код выглядит следующим образом

// request.js
import axios from 'axios';
import * as qs from 'qs';

declare const SERVICE: string;

axios.defaults.baseURL = SERVICE;
axios.defaults.withCredentials = true;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.headers.put['Content-Type'] = 'application/x-www-form-urlencoded';

// qs 序列化 防止XSRF攻击 可以对深层次的json array进行序列化
axios.interceptors.request.use((config: any): any => {
    if (config.url.indexOf('?') !== -1) {
        config.url += `&t=${new Date().getTime()}`;
    } else {
        config.url += `?t=${new Date().getTime()}`;
    }
    // `transformRequest` 允许在向服务器发送前,修改请求数据
    // 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
    // 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
    config.transformRequest = [(data: any, headers: any) => {
        return qs.stringify(data, {
            allowDots: true
        })
    }];
    // `paramsSerializer` 是一个负责 `params` 序列化的函数
    config.paramsSerializer = (params: any) => {
        return qs.stringify(params, {
            arrayFormat: 'repeat'
        })
    };
    return config;
}, (error: any) => {
    return Promise.reject(error);
});

axios.interceptors.response.use((response: any): any => {
    const { data } = response;
    if(data.code === 2){
        window.location.href = `/login?from=${window.location.pathname}`;
    }
    return response;
}, (error: any) => {
    Promise.reject(error);
});

export default axios;
// action.js
import axios from './request';
axios.get('')
    .then(res = > {
        // 业务代码
    })
    .catch(err => {
        // 业务代码
    })