上一小节中,我们还存在一个问题未处理,就是跨域访问问题。更多跨域说明,可以查看跨域
详细的 proxy 技术可以查阅其他资料,这里我只做简要说明:之所以会出现跨域访问问题,是因为浏览器的安全策略。所以我们预想是不是有一种方式,能够绕过浏览器的安全策略?
那就是先请求一个同源服务器,再由服务器去请求其他的服务器。比如:
- 我们本来是要请求
https://pvp.qq.com
服务器,但是它存在跨域。 - 所以我们先请求了
http://localhost:3000
(假设的),它不存在跨域问题,所以它受理了我们的请求,并且我们可以取得它返回的数据。 - 而由
http://localhost:3000
返回的数据,又是从真实的https://pvp.qq.com
获取来的,因为服务端不是在浏览器环境,所以就没有浏览器的安全策略问题。 - 因为
http://localhost:3000
(假设的)这个服务器,它只是把我们请求的参数,转发到真实服务端,又把真实服务端下发的数据,转发给我们,所以我们称它为代理。
umi 提供了 proxy 来处理这个问题。
配置 proxy
要在 umi 中使用 proxy 非常简单,只要在配置文件中配置就可以了。
./.umirc.js
export default {
plugins: [
...
],
"proxy": {
"/api": { ---step1
"target": "https://pvp.qq.com", ---step2
"changeOrigin": true, ---step3
"pathRewrite": { "^/api" : "" } ---step4
}
}
}
注意层级,proxy在最外层,不要写到插件plugins里面
- step1 设置了需要代理的请求头,比如这里定义了
/api
,当你访问如/api/abc
这样子的请求,就会触发代理 - step2 设置代理的目标,即真实的服务器地址
- changeOrigin 设置是否跨域请求资源
- pathRewrite 表示是否重写请求地址,比如这里的配置,就是把
/api
替换成空字符
src/app.ts
import { ResponseError } from 'umi-request';
export const request = {
- prefix: 'https://pvp.qq.com',
+ prefix: '/api',
errorHandler: (error: ResponseError) => {
// 集中处理错误
console.log(error);
},
};
修改请求地址,前缀改成 /api
,其实通过代理,最后真实访问的地址还是 https://pvp.qq.com/web201605/js/herolist.json
这时候我们就取到了网络上的数据了。
代理只是请求服务代理,不是请求地址
我们打开控制台,可以看到我们的请求地址是 http://localhost:8000/api/web201605/js/herolist.json
,响应200,并返回了真实数据。
你不会在浏览器的控制台中查看到我们真实代理的地址,这里需要注意,代理只是将请求服务做了中转,设置proxy不会修改请求地址。
最小成本设置proxy
这里指的是后续和服务端对接的时候,如何优雅的设置 proxy 。
step1
向服务端要一个,不需要授权,不需要登录,get请求的接口。
如:https://api.douban.com/v2/movie/in_theaters
step2
将服务端给我们的地址,直接在浏览器中访问,如果能正确返回数据,那说明服务端给的接口没有问题。
如果返回错误,那就可以先不往下进行了,可以先让服务端修正他的错误
step3
查看接口文档,设置正确的代理前缀。
比如接口是 /v1/abc
/v2/sss
/v2/xxx
这样的,那target应该是 https://api.douban.com/
比如接口是 /v2/abc
/v2/sss
/v2/xxx
这样的,那target应该是 https://api.douban.com/v2/
step 4
设置 proxy
比如接口是 /v1/abc
/v2/sss
/v2/xxx
这样的,那target应该是 https://api.douban.com/
"proxy": {
"/api": {
"target": "https://api.douban.com/",
"changeOrigin": true,
"pathRewrite": { "^/api" : "" }
}
}
请求地址 /api/v1/abc
/api/v2/sss
/api/v2/xxx
比如接口是 /v2/abc
/v2/sss
/v2/xxx
这样的,那target应该是 https://api.douban.com/v2/
"proxy": {
"/api": {
"target": "https://api.douban.com/v2/",
"changeOrigin": true,
"pathRewrite": { "^/api" : "" }
}
}
请求地址 /api/abc
/api/sss
/api/xxx
step 5
如果你如上操作还是不行,请不要想为什么设置proxy无效,到底proxy要怎么设置,这样的问题。
也不要去问任何人,在任何开源项目的iss里面提问题,因为他们能够给你的帮助,不会比上述更详细了。
不行,只有一个问题,那就是你不够细心,设置错误咯,那就从step1再走一回,加油吧!少年