axios基本使用
const instance = axios.create({
baseURL: `https://xx`,
})
// 1.
instance.get('/project/getList', {
params: {
}
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
// 2.
instance({
method: 'get',
url: '/project/getList',
params: {
}
})
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
前端检查登录态,进行请求拦截
instance.interceptors.request.use(config => {
const { isLogin } = checkLogin();
if (!isLogin) {
login();
}
return config;
});
后端检查登录态,前端进行响应拦截
如果后端校验登录态,那么前端需要在登录态失效的时候,进行拦截,并跳转到统一登录地址,具体实现如下:
import axios from 'axios';
import { message } from 'ant-design-vue';
const instance = axios.create({
baseURL: `https://${location.host}/your-address`,
});
instance.interceptors.response.use(
res => {
const { iRet, data, sMsg, status } = res.data;
if (iRet === 0 || status === 200) {
return { data, sMsg };
} else if (iRet === -99) {
// 登录态失效,重新登录
const current_key = 'key';
const checkUrl = `callbackURL?lastUrl=${encodeURI(
location.href,
)}`;
window.location.href = `https://passport.com&key=${current_key}&url=${checkUrl}`;
} else {
console.log(`接口拦截 - ${iRet}`, sMsg);
message.error(sMsg);
return Promise.reject(sMsg);
}
},
err => {
// 非 2xx 范围内的状态码都会触发该函数。
console.log('接口拦截 - 非2xx状态码', err);
return Promise.reject(err);
},
);
// 方法1:可对每个请求统一处理
export const fetch = config => {
return instance(config);
};
// 方法2:更简单
export default instance
// 方法1
import { fetch } from './fetch';
export const getList = params => {
return fetch({
method: 'get',
url: '/project/getList',
params,
});
};
// 方法2
import instance from './fetch';
export const getList = params => {
return instance({
method: 'get',
url: '/project/getList',
params,
});
};
case1:返回数据格式
描述
当申请接口时,后端返回的是javascript字符串,如下:
var result = "{"ret":1,"msg":"\u6570\u636e\u83b7\u53d6\u6210\u529f","data":"","script.."
第一种方式:请求URL加上参数
请求URL加上format=json参数或者是type=json通常是API设计者提供的一种方式,用于指定返回数据的格式。当你在请求URL中添加这个参数时,API服务器会根据这个参数返回JSON格式的数据。
第二种方式:设置Accept头部
可以在创建axios实例时通过设置headers属性来指定Accept头部信息。
const instance = axios.create({
baseURL: `https://a.com/`,
withCredentials: true,
headers: {
'Accept': 'application/json'
}
});
第三种方式:匹配js字符串
如果后端接口没有设计为根据请求头中的Accept字段或者请求参数中的format来返回不同格式的数据,那么即使在前端请求中指定Accept: application/json或者添加format=json参数,也无法强制后端返回JSON格式的数据。后端服务需要明确支持这种内容协商机制,才能根据客户端的请求返回不同格式的响应。
//假设responseText是API返回的响应文本
let responseText = 'var result = {"key": "value"};';
// 使用正则表达式匹配JSON对象
let jsonMatch = responseText.match(/var result = (.*);/);
if (jsonMatch && jsonMatch[1]) {
// 尝试解析匹配到的字符串为JSON对象
try {
let jsonData = JSON.parse(jsonMatch[1]);
console.log(jsonData); // 这里是解析后的JSON对象
} catch (e) {
console.error('解析JSON失败:', e);
}
}
case2: 发送数据格式
描述
在开发中,遇到post请求数据除了请求载荷,还有表单数据,导致前端发请求无法得到正确回应:
当采用post发送请求时,形如:
import axios from 'axios';
// 创建axios实例
const instance = axios.create({
baseURL: 'http://your-api-base-url.com', // 你的API基础URL
timeout: 1000, // 请求超时时间
// 其他配置...
});
// 发送GET请求
instance({
method: 'get',
url: '/your-endpoint',
}).then(response => {
console.log(response.data); // 处理响应数据
}).catch(error => {
console.error(error); // 处理错误情况
});
// 发送POST请求
instance({
method: 'post',
url: '/your-endpoint',
data: {
key: 'value', // 这里放置你要发送的数据
}
}).then(response => {
console.log(response.data); // 处理响应数据
}).catch(error => {
console.error(error); // 处理错误情况
});
第一种方式:使用formData创造对象
- 当传入data为对象,axios会自动转化为JSON字符串(显示为请求载荷);
- 当传入data为
FormData对象,axios会自动转化为表单数据(显示为表单数据)
let formData = new FormData();
formData.append('key1', 'value1');
formData.append('key2', 'value2');
axios.post('/your-endpoint', formData);
// 如果是请求载荷
let payload = {
key1: 'value1',
key2: 'value2'
};
axios.post('/your-endpoint', payload);
第二种方式:设置headers为{'Content-Type': 'application/x-www-form-urlencoded'}
instance({
method: 'post',
url: '/module/other/index.php?c=ruleQual&a=modifyQual&type=json',
data,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).then().catch()
另外,一个请求可以既可以有data 又可以有params:
export const update = ({params, data}) => {
return instance({
method: 'post',
url: '/a=update&type=json&',
params,
data,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});
};
axios捕获错误
第一种方式:async/await + try/catch 捕获同步错误
async create() {
let self = this;
try {
const res = await axios.post(`https://${self.apiHost}/${self.testPath}/operation/create`,
{
params,
},
{
withCredentials: true
}
)
if (res.data.iRet == 0) {
console.log('success')
}
} catch(err) {
console.log('err', err);
}
}
try/catch捕获同步错误:
try {
console.log(res);
}
catch (error) {
// 捕获到错误,并在控制台输出错误信息
console.error('捕获到同步错误:', error.message);
}
第二种方式:.then 捕获异步错误
const api = axios.create({
baseURL: `https://${apiHost}`,
withCredentials: true,
});
const create = data => {
return api({
method: "post",
url: `/${testPath}/operation/create`,
data,
});
create({
params
})
.then(() => {
console.log('success')
})
.catch(err => {
console.log("err", err);
});
Cookie
Cookie 设置
cookie 通常由服务器通过 HTTP 响应头 Set-Cookie 发送给客户端,然后客户端会存储这些cookie信息。在后续的请求中,浏览器会自动将这些cookie信息附加到请求头中,发送给服务器。
跨域请求带 Cookie
当涉及到跨域请求时,默认情况下,浏览器出于安全考虑不会发送cookie。但是,如果你希望在跨域请求中包含cookie,你需要在前端的请求中设置 withCredentials 为 true。同时,服务器也需要设置响应头 Access-Control-Allow-Credentials 为 true,并且 Access-Control-Allow-Origin 不能设置为 *,它必须指定为请求页面的源。
跨域
这里所说的跨域问题,只能说是绕过浏览器的安全策略。
跨域请求由客户端发出后,会带有origin请求头,返回时候如果带有Access-Control-Allow-Origin字段,那么预检请求通过了,后续发送同一api的请求,就不再需要预检请求。当正常发送get或者post请求,返回的请求头中仍然带有Access-Control-Allow-Origin字段,如果没有该字段,或者该字段的值不允许当前源访问,浏览器将不会返回响应内容给JavaScript代码,而是在控制台中报出一个跨域错误。并且下一次访问该api时重新发送预检请求。如果预检请求没通过,那么浏览器端会直接拦截客户端发出的同api请求。
对于简单请求(GET、POST和一些HEAD请求),浏览器直接发送请求,但是响应必须包含Access-Control-Allow-Origin头信息,否则浏览器同样会阻止响应。
CORS
1、普通跨域请求:只需服务器端设置Access-Control-Allow-Origin
2、带cookie跨域请求:前后端都需要进行设置
【前端设置】根据withCredentials字段判断是否带有cookie
Nginx反向代理
为后端返回的请求设置了Access-Control-Allow-Origin,这样一来,在前端的开发服务器中就不需要再配置跨域。
Nginx反向代理在线上环境下非常有用,主要是因为它提供了一系列的功能和优势,这些在本地开发环境中通常不是必需的,或者可以通过其他简单的方式实现。例如:负载均衡
server {
listen 80;
server_name example.com;
location / {
root /path/to/your/app;
index index.html;
}
location /api {
proxy_pass http://backend-api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header 'Access-Control-Allow-Origin' '*';
}
}
Webpack本地代理和whistle
Whistle 是一种开发环境代理方案。它是一个基于Node.js的跨平台web调试工具,可以用来拦截和修改HTTP、HTTPS、WebSocket等网络请求。Whistle 提供了丰富的功能,比如请求转发、响应模拟、性能优化、安全检查等,非常适合前端开发者和测试工程师使用。
与Webpack的本地代理功能相比,Whistle 提供了更为强大和灵活的网络请求处理能力。Webpack的代理主要是在开发环境中解决前后端分离时的跨域问题,通常配置在webpack.config.js文件的devServer.proxy选项中。而Whistle 不仅可以用于本地开发环境,还可以用于测试环境和生产环境的网络请求调试和优化。