🎉 前言
这几天在学习前端的时候需要写一个实例,是关于翻译功能的。于是便想着在网上找一些API看能不能调用。这里遇到一个很坑的问题,就是我在暑假学习的时候曾经调用过心知天气的API、QQ音乐的API和今日头条的API,都未曾遇到过跨域问题,但是现在找了一大堆的翻译API,全都会遇到跨域问题,看来是无法避免要解决它了。其实每个初学前端的人都遇到过这个问题,可能会觉得这个问题非常棘手,网上也没有一个统一的解决方案,一开始我也是这么觉得的,但我发现了一个可行性还是比较高的方法,在这里做一下记录和分享。
🎉 什么是跨域
我采用的方法是使用nginx正向代理解决跨域问题。简单讲一下实现原理。首先,我们知道,浏览器在处理不同域名之间的通信和请求时,会自动触发同源保护机制。对于我们自己的项目,只要在后端代码中添加一个响应头即可,但是就像我现在面临的处境,我是在调用百度翻译的API,自然不可能去修改百度的后端代码。
于是,我看了一些网上的资料,得到了一个启发:既然这是浏览器的一种保护机制,那么有没有什么方法可以先让浏览器去请求本地的服务器,本地服务器再去请求远程服务器,也就是说让本地服务器充当一个中间代理的角色,浏览器与本地服务器之间通信自然就不会存在跨域问题了。
看到这里,很多读者可能就会想到,这不就是nginx的作用吗,没错,接下来我们就要去借助nginx为我们代理请求,从而解决跨域问题。
🎉 前期准备
这里推荐使用集成工具去下载和管理nginx,我自己使用的是PhpWebStudy ,即使你之前已经下载过了nginx,我还是推荐这个工具,这个工具在管理本地各种配置方面非常有帮助。当然,如果你不想下载,也不影响后续配置,只要下载了ngixn即可,但是后续讲解会以PhpWebStudy这款软件为基础。
🎉 配置代理
打开PhpwebStudy,进入如下页面:
(如果没有安装nginx,先根据软件提示安装好nginx)
打开配置文件,找到http模块下的server模块开始编写配置,配置模版如下:
server {
listen 80;
server_name yourdomain.com;
location /api {
proxy_pass http://api.example.com; # 转发请求到后端 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;
proxy_set_header X-Forwarded-Proto $scheme;
# 解决跨域问题
add_header 'Access-Control-Allow-Origin' '*'; # 允许所有来源跨域请求
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; # 允许的方法
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept, Authorization';
# 处理预检请求
if ($request_method = 'OPTIONS') {
return 204; # 对于 OPTIONS 请求直接返回204,无内容响应
}
}
}
简单解释一下,这里我将location
设置成了/test
,server_name
配置成了localhost
,proxy_pass
配置成了百度翻译的API请求地址(proxy_pass就是代理的地址)http://api.fanyi.baidu.com/api/trans/vip/translate
,这三项配置完成之后,重启ngixn,然后在浏览器地址栏输入localhost/test
,会得到以下回复:
说明我们已经配置好了本地代理,具体表现在我们访问本机(localhost)地址会被nginx代理到百度翻译的api接口。
🎉代码实现
translate() {
that = this
let originalString = "AppId" + this.srcContent + "1435660288"+"secretKey"
let sign = CryptoJS.MD5(originalString).toString();
axios.get('http://127.0.0.1/test', {
params: {
q: this.srcContent, // 参数名 'q' 应该与百度翻译 API 匹配
from: 'en',
to: 'zh',
appid: 'AppId',
salt: '1435660288',
sign: sign
}
}).then(
function (response) {
console.log(response.data.trans_result[0].dst);
that.dstContent = response.data.trans_result[0].dst;
},
function (err) {
console.log(err);
}
)
}
大家可以参考一下,AppId和secretKey替换成你们自己申请的AppId和密钥,具体参考这篇文档:百度开发者文档,由于这篇文章重点不在于此,因此不再深入。
🎉 解决重定向问题
最后在代码中实现请求的时候,在浏览器中打开总是会重定到百度翻译的网页端,而不是百度翻译的API接口,为了解决这个问题,我还思考了很久,但解决方法却比较简单,具体原理不甚清楚,就是将
proxy_set_header Host $host;
改成
proxy_set_header Host api.fanyi.baidu.com
这样就可以确保代理请求被正确识别并发送到百度翻译 API了。
OK,今天的分享就到这里,可能有些地方讲的不够清楚详细,大家可在评论区里评论,我会尽量为大家解答。