详解vue或uni-app的跨域问题解决方案


Posted in Javascript onFebruary 21, 2020

常见解决方案有两种

服务器端解决方案

服务器告诉浏览器:你允许我跨域

具体如何告诉浏览器,请看:

// 告诉浏览器,只允许 http://bb.aaa.com:9000 这个源请求服务器
$response->header('Access-Control-Allow-Origin', 'http://bb.aaa.com:9000');
// 告诉浏览器,请求头里只允许有这些内容
$response->header('Access-Control-Allow-Headers', 'Authorization, Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, X-Requested-By, If-Modified-Since, X-File-Name, X-File-Type, Cache-Control, Origin');
// 告诉浏览器,只允许暴露'Authorization, authenticated'这两个字段
$response->header('Access-Control-Expose-Headers', 'Authorization, authenticated');
// 告诉浏览器,只允许GET, POST, PATCH, PUT, OPTIONS方法跨域请求
$response->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, OPTIONS');
// 预检
$response->header('Access-Control-Max-Age', 3600);

将以上代码写入中间件:

// /app/Http/Middleware/Cors.php
<?php
namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Response;
class Cors {

  /**
   * Handle an incoming request.
   *
   * @param \Illuminate\Http\Request $request
   * @param \Closure $next
   * @return mixed
   */
  public function handle($request, Closure $next)
  {
    $response = $next($request);
    // 告诉浏览器,只允许 http://bb.aaa.com:9000 这个源请求服务器
    $response->header('Access-Control-Allow-Origin', 'http://bb.aaa.com:9000');
    // 告诉浏览器,请求头里只允许有这些内容
    $response->header('Access-Control-Allow-Headers', 'Authorization, Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, X-Requested-By, If-Modified-Since, X-File-Name, X-File-Type, Cache-Control, Origin');
    // 告诉浏览器,只允许暴露'Authorization, authenticated'这两个字段
    $response->header('Access-Control-Expose-Headers', 'Authorization, authenticated');
    // 告诉浏览器,只允许GET, POST, PATCH, PUT, OPTIONS方法跨域请求
    $response->header('Access-Control-Allow-Methods', 'GET, POST, PATCH, PUT, OPTIONS');
    // 预检
    $response->header('Access-Control-Max-Age', 3600);
    return $response;
  }

}

在路由上添加跨域中间件,告诉客户端:服务器允许跨域请求

$api->group(['middleware'=>'cors','prefix'=>'doc'], function ($api) {
  $api->get('userinfo', \App\Http\Controllers\Api\UsersController::class.'@show');
  
})

客户器端解决方案

欺骗浏览器,让浏览器觉得你没有跨域(其实还是跨域了,用的是代理)

在manifest.json里添加如下代码:

// manifest.json
"devServer" : {
  "port" : 9000,
  "disableHostCheck" : true,
  "proxy": {
    "/api/doc": {
      "target": "http://www.baidu.com",
      "changeOrigin": true,
      "secure": false
    },
    "/api2": {
     .....
    }
  },
  
},

参数说明

'/api/doc'

捕获API的标志,如果API中有这"/api/doc"个字符串,那么就开始匹配代理,
比如API请求"/api/doc/userinfo",
会被代理到请求 "http://www.baidu.com/api/doc"
即:将匹配到的"/api/doc"替换成"http://www.baidu.com/api/doc"
客户端浏览器最终请求链接表面是:"http://192.168.0.104:9000/api/doc/userinfo",
实际上是被代理成了:"http://www.baidu.com/api/doc/userinfo"去向服务器请求数据

target

代理的API地址,就是需要跨域的API地址。
地址可以是域名,如:http://www.baidu.com
也可以是IP地址:http://127.0.0.1:9000
如果是域名需要额外添加一个参数changeOrigin: true,否则会代理失败。

pathRewrite

路径重写,也就是说会修改最终请求的API路径。
比如访问的API路径:/api/doc/userinfo,
设置pathRewrite: {'^/api' : ''},后,
最终代理访问的路径:"http://www.baidu.com/doc/userinfo",
将"api"用正则替换成了空字符串,
这个参数的目的是给代理命名后,在访问时把命名删除掉。

changeOrigin

这个参数可以让target参数是域名。

secure

secure: false,不检查安全问题。
设置后,可以接受运行在 HTTPS 上,可以使用无效证书的后端服务器

其他参数配置查看文档
https://webpack.docschina.org/configuration/dev-server/#devserver-proxy

请求封装

uni.docajax = function (url, data = {}, method = "GET") {
 return new Promise((resolve, reject) => {
  var type = 'application/json'
  if (method == "GET") {
   if (data !== {}) {
    var arr = [];
    for (var key in data) {
     arr.push(`${key}=${data[key]}`);
    }
    url += `?${arr.join("&")}`;
   }
   type = 'application/x-www-form-urlencoded'
  }
  var access_token = uni.getStorageSync('access_token')
  console.log('token:',access_token)
  var baseUrl = '/api/doc/'
  uni.request({
   url: baseUrl + url,
   method: 'GET',
   data: data,
   header: {
    'content-type': type,
    'Accept':'application/x..v1+json',
    'Authorization':'Bearer '+access_token,
   },
   success: function (res) {
    if (res.data) {
     resolve(res.data)
    } else {
     console.log("请求失败", res)
     reject(res)
    }
   },
   fail: function (res) {
    console.log("发起请求失败~")
    console.log(res)
   }
  })
 })
}

请求示例:

//获取用户信息
uni.docajax("userinfo",{},'GET')
.then(res => {
  this.nickname = res.nickname
  this.avatar = res.avatar
});

到此这篇关于详解vue或uni-app的跨域问题解决方案的文章就介绍到这了,更多相关vue或uni-app的跨域问题解决方案内容请搜素三水点靠木以前的文章或下面相关文章,希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
JavaScript 的方法重载效果
Aug 07 Javascript
JavaScript对象、属性、事件手册集合方便查询
Jul 04 Javascript
js使下拉列表框可编辑不止是选择
Dec 12 Javascript
js分页代码分享
Apr 28 Javascript
如何解决谷歌浏览器下jquery无法获取图片的尺寸
Sep 10 Javascript
JavaScript prototype属性详解
Oct 25 Javascript
Angular的模块化(代码分享)
Dec 26 Javascript
微信小程序 navbar实例详解
May 11 Javascript
node.js中express中间件body-parser的介绍与用法详解
May 23 Javascript
关于HTTP传输中gzip压缩的秘密探索分析
Jan 12 Javascript
ionic使用angularjs表单验证(模板验证)
Dec 12 Javascript
javascript中的数据类型检测方法详解
Aug 07 Javascript
如何基于js判断浏览器版本
Feb 20 #Javascript
微信小程序webSocket的使用方法
Feb 20 #Javascript
Javascript Worker子线程代码实例
Feb 20 #Javascript
vue中音频wavesurfer.js的使用方法
Feb 20 #Vue.js
Javascript原生ajax请求代码实例
Feb 20 #Javascript
webpack中的模式(mode)使用详解
Feb 20 #Javascript
jquery向后台提交数组的代码分析
Feb 20 #jQuery
You might like
跟我学小偷程序之成功偷取首页(第三天)
2006/10/09 PHP
PHP insert语法详解
2008/06/07 PHP
php如何实现只替换一次或N次
2015/10/29 PHP
浅析php静态方法与非静态方法的用法区别
2016/05/17 PHP
PHP实现的多进程控制demo示例
2019/07/22 PHP
JavaScript 事件参考手册
2008/12/24 Javascript
Javascript 代码也可以变得优美的实现方法
2009/06/22 Javascript
JS拖动技术 关于setCapture使用
2010/12/09 Javascript
跨域传值即主页面与iframe之间互相传值
2013/12/09 Javascript
JS替换字符串中字符即替换全部而不是第一个
2014/06/04 Javascript
BootStrap实现手机端轮播图左右滑动事件
2016/10/13 Javascript
网站发布后Bootstrap框架引用woff字体无法正常显示的解决方法
2016/11/24 Javascript
JS中解决谷歌浏览器记住密码输入框颜色改变功能
2017/02/13 Javascript
jQuery插件zTree实现的基本树与节点获取操作示例
2017/03/08 Javascript
bootstrap插件treeview实现全选父节点下所有子节点和反选功能
2017/07/21 Javascript
浅析Angular19 自定义表单控件
2018/01/31 Javascript
fullpage.js最后一屏滚动方式
2018/02/06 Javascript
JavaScript实现简单的隐藏式侧边栏功能示例
2018/08/31 Javascript
解决Vue2.0中使用less给元素添加背景图片出现的问题
2018/09/03 Javascript
解决layui批量传值到后台操作时出现传值为空的问题
2019/09/28 Javascript
vue + elementUI实现省市县三级联动的方法示例
2019/10/29 Javascript
Python实现的文本简单可逆加密算法示例
2017/05/18 Python
python 函数传参之传值还是传引用的分析
2017/09/07 Python
python 多线程重启方法
2019/02/18 Python
利用python实现凯撒密码加解密功能
2020/03/31 Python
Pandas之缺失数据的实现
2021/01/06 Python
HTML5实现WebSocket协议原理浅析
2014/07/07 HTML / CSS
计算机应用毕业生自荐信
2013/10/23 职场文书
店长助理岗位职责
2013/12/13 职场文书
关于幼儿的自我评价
2013/12/18 职场文书
投标授权委托书范文
2014/08/02 职场文书
2014大学校园光棍节活动策划书
2014/09/29 职场文书
成都人事代理协议书
2014/10/25 职场文书
2014财务部年度工作总结
2014/12/08 职场文书
Python入门学习之类的相关知识总结
2021/05/25 Python
浅谈如何保证Mysql主从一致
2022/03/13 MySQL