一、跨域日志报错
我们由于项目需要经常会需要对不同域名、不同子域的网站接口发起请求,有时甚至是对于同一域名的不同端口发起请求,此时我们经常看到以下报错:
Access to XMLHttpRequest at 'xxx' from origin 'xxx' has been blocked by CORS
policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
是的,错误的原因就是你跨域了。
二、为什么会有跨域问题?
看到网上举的一个形象例子,先设想下,如果允许跨域,那么黑衣人是不是可以在自己的网页上把请求转发给其他网站?例如,黑衣人在自己的页面设计了一个跨域请求到某钱堆的网址,当用户访问黑衣人网址时,浏览器按照黑衣人设计去访问了钱堆(还携带了用户在钱堆那儿的cookie)......之后,之后警察叔叔们又要加班了。还有诸如此类许多安全隐患。所以后来的浏览器都开始实行同源策略。
同源策略,其实就是只允许相同协议+域名+端口号(如存在)的HTTP请求互相访问。这么理解其实就够了。关于跨域资源共享标准( cross-origin sharing standard )CORS的详细内容
三、怎么解决跨域问题?
这里我给出两种React的跨域解决方案(React16.9),第一种比较实用,第二种需要服务端协调。
很多以前的资料写的直接在package.json中配置proxy的,这个方法已经失效很久了。官方给出的新版本解决方案需要借助http-proxy-middleware这个包。
1. 方法一: 使用 http-proxy-middleware
1> . 添加组件
npm install --save http-proxy-middleware
2>. src目录下创建setupProxy.js,配置如下:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function (app) {
// proxy第一个参数为要代理的路由 第二参数中target为代理后的请求网址,
// changeOrigin是否改变请求头,其他参数请看官网 baidu
app.use(createProxyMiddleware('/cityjson', {
target: 'http://pv.sohu.com',
changeOrigin: true,
} ));
}
3>. 测试一下:
// 页面代码:
import React,{ useEffect,useState } from 'react';
import axios from 'axios';
function App() {
const [ip,setIp] = useState();
axios.get('/cityjson').then((res) => {
console.log(res.data);
setIp(res.data.toString());
}).catch(function (error) {
console.log(error);
});
return (<h1>获取的IP信息:{ip}</h1>) ;
}
export default App;
成功获取! web页面显示:
获取的IP信息:var returnCitySN = {"cip": "117.136.83.208", "cid": "CN", "cname": "CHINA"};
2.借助服务端配置