1. 什么是跨域?
跨域一词从字面意思看,就是跨域名嘛,但实际上跨域的范围绝对不止那么狭隘。具体概念如下:只要协议、域名、端口有任何一个不同,都被当作是不同的域。之所以会产生跨域这个问题呢,其实也很容易想明白,要是随便引用外部文件,不同标签下的页面引用类似的彼此的文件,浏览器很容易懵逼的,安全也得不到保障了就。什么事,都是安全第一嘛。但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦。所以我们要通过一些方法使本域的js能够操作其他域的页面对象或者使其他域的js能操作本域的页面对象(iframe之间)。
在前端领域中,跨域是指浏览器允许向服务器发送跨域请求,从而克服Ajax只能同源使用的限制。
这里我们需要注意两点:
如果是协议和端口造成的跨域问题“前台”是无能为力的;
在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上(“URL的首部”指window.location.protocol +window.location.host,也可以理解为“Domains, protocols and ports must match”。)
2.如何处理跨域?
yarn add http-proxy-middleware
下载基于 promise 的 HTTP 库axios
yarn add axios
暴露配置项
npm run eject
//或者
yarn eject
注意:如果执行上述命令失败,配置项未展示,可能是项目在初始化时默认关联git仓库,我们需要提交修改,然后在执行则成功!
首先在src下创建setupProxy.js文件
const { createProxyMiddleware } = require("http-proxy-middleware");
module.exports = function (app) {
app.use(
"/devApi",
createProxyMiddleware({
target: "http://www.web-jshtml.cn/api/react",
changeOrigin: true,
pathRewrite: {
"^/devApi": "",
},
})
);
};
注意:http-proxy-middleware更早版本引入const proxy = require("http-proxy-middleware"),这也是大部分会出错的地方!
配置好setupProxy.js文件后,查看start eject展示出来的config文件夹下面paths.js中setupProxy的路径
proxySetup: resolveApp('src/setupProxy.js'),
如果您也很顺利,到这跨域已经处理完毕 :)
3.如何封装请求?
创建request
import axios from "axios";
//创建实例
const service = axios.create({
baseURL: process.env.REACT_APP_API,
timeout: 5000,
});
//请求拦截
service.interceptors.request.use(
function (config) {
console.log(process.env.REACT_APP_API);
// 在发送请求之前做些什么
return config;
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error);
}
);
//响应拦截
service.interceptors.response.use(
function (response) {
// 对响应数据做点什么
return response;
},
function (error) {
// 对响应错误做点什么
return Promise.reject(error);
}
);
export default service;
注意:
process.env.REACT_APP_API等于"/devApi"
process.env.NODE_ENV可以获取当前环境是开发环境还是生产环境
REACT_APP_API变量定义在.env.development文件中
REACT_APP_API="/devApi"
注意:我们不仅可以创建.env.development来表示开发环境api,还可以创建.env.production来表示生产环境,程序会根据环境自动读取不同API
根据功能模块创建请求
import service from "../../src/utils/request";
/**
* 登录接口
*/
export function Login(data) {
return service.request({
url: "/login/",
method: "POST",
data,
});
}
组件调用
import { Login } from "../../api/account";
onFinish = (values) => {
Login(values)
.then((res) => {
message.success("登录成功");
console.log(res);
})
.catch((err) => {
console.log(err);
});
console.log("Received values of form: ", values);
};
惟愿山河无恙,国泰民安,幸哉~