详解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 相关文章推荐
IE6/7/8/9不支持exec的简写方式
May 25 Javascript
javascript针对DOM的应用分析(四)
Apr 15 Javascript
Jquery动态更改一张位图的src与Attr的使用
Jul 31 Javascript
jQuery CSS()方法改变现有的CSS样式表
Sep 09 Javascript
让JavaScript中setTimeout支持链式操作的方法
Jun 19 Javascript
javascript获取网页各种高宽及位置的方法总结
Jul 27 Javascript
Jquery获取radio选中的值
May 05 jQuery
D3.js进阶系列之CSV表格文件的读取详解
Jun 06 Javascript
原生JS实现动态加载js文件并在加载成功后执行回调函数的方法
Dec 30 Javascript
原生JS实现的自动轮播图功能详解
Dec 28 Javascript
JavaScript判断对象和数组的两种方法
May 31 Javascript
浅谈Vue使用Cascader级联选择器数据回显中的坑
Oct 31 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
php curl 上传文件代码实例
2015/04/27 PHP
通过Mootools 1.2来操纵HTML DOM元素
2009/09/15 Javascript
jquery attr 设定src中含有&amp;(宏)符号问题的解决方法
2011/07/26 Javascript
javascript 进阶篇3 Ajax 、JSON、 Prototype介绍
2012/03/14 Javascript
Extjs4 关于Store的一些操作(加载/回调/添加)
2013/04/18 Javascript
js定时调用方法成功后并停止调用示例
2014/04/08 Javascript
js获取鼠标点击的位置实现思路及代码
2014/05/09 Javascript
js监控IE火狐浏览器关闭、刷新、回退、前进事件
2014/07/23 Javascript
jquery实现可自动收缩的TAB网页选项卡代码
2015/09/06 Javascript
使用jquery动态加载Js文件和Css文件
2015/10/24 Javascript
Jquery on方法绑定事件后执行多次的解决方法
2016/06/02 Javascript
利用JS实现页面删除并重新排序功能
2016/12/09 Javascript
详解JS数据类型的值拷贝函数(深拷贝)
2017/07/13 Javascript
小程序tab页无法传递参数的方法
2018/08/03 Javascript
element-ui表格数据转换的示例代码
2018/08/24 Javascript
VUE DOM加载后执行自定义事件的方法
2018/09/07 Javascript
基于Vue SEO的四种方案(小结)
2019/07/01 Javascript
es6中reduce的基本使用方法
2019/09/10 Javascript
Angular之jwt令牌身份验证的实现
2020/02/14 Javascript
python33 urllib2使用方法细节讲解
2013/12/03 Python
使用Python的Flask框架实现视频的流媒体传输
2015/03/31 Python
python实现统计代码行数的方法
2015/05/22 Python
python遍历目录的方法小结
2016/04/28 Python
pyqt5实现绘制ui,列表窗口,滚动窗口显示图片的方法
2019/06/20 Python
python开启debug模式的方法
2019/06/27 Python
Python文件路径名的操作方法
2019/10/30 Python
Python应用实现双指数函数及拟合代码实例
2020/06/19 Python
家乐福巴西网上超市:Carrefour巴西
2016/10/31 全球购物
国外平面设计素材网站:The Hungry JPEG
2017/03/28 全球购物
Python文件操作的面试题
2013/06/22 面试题
美术专业学生个人自我评价
2013/09/19 职场文书
企业文化建设实施方案
2014/03/22 职场文书
人力资源管理毕业生自荐信
2014/06/26 职场文书
平凡的世界读书笔记
2015/06/25 职场文书
国际贸易实训总结
2015/08/03 职场文书
纪检部部长竞选稿
2015/11/21 职场文书