详解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 相关文章推荐
经验几则 推荐
Sep 05 Javascript
Jquery 设置标题的自动翻转
Oct 03 Javascript
Dom 是什么的详细说明
Oct 25 Javascript
cookie在javascript中的使用技巧以及隐私在服务器端的设置
Dec 03 Javascript
动态的9*9乘法表效果的实现代码
May 16 Javascript
jQuery实现的表格展开伸缩效果实例
Sep 07 Javascript
vue滚动轴插件better-scroll使用详解
Oct 17 Javascript
新年快乐! javascript实现超级炫酷的3D烟花特效
Jan 30 Javascript
vue实现动态显示与隐藏底部导航的方法分析
Feb 11 Javascript
基于leaflet.js实现修改地图主题样式的流程分析
May 15 Javascript
基于js实现数组相邻元素上移下移
May 19 Javascript
利用React高阶组件实现一个面包屑导航的示例
Aug 23 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
IIS+PHP+MySQL+Zend配置 (视频教程)
2006/12/13 PHP
php调用mysql存储过程
2007/02/14 PHP
php的XML文件解释类应用实例
2014/09/22 PHP
PHP给源代码加密的几种方法汇总(推荐)
2018/02/06 PHP
PHP mkdir创建文件夹实现方法解析
2020/11/13 PHP
前端开发过程中浏览器版本的两种判定方法
2013/10/30 Javascript
Javascript基础教程之JavaScript语法
2015/01/18 Javascript
JS实现的另类手风琴效果网页内容切换代码
2015/09/08 Javascript
jQuery实现多级联动下拉列表查询框
2016/01/18 Javascript
bootstrap警告框示例代码分享
2017/05/17 Javascript
React实践之Tree组件的使用方法
2017/09/30 Javascript
详解angular2.x创建项目入门指令
2018/10/11 Javascript
jquery ajax 请求小技巧实例分析
2019/11/11 jQuery
VUEX-action可以修改state吗
2019/11/19 Javascript
vue导入.md文件的步骤(markdown转HTML)
2020/12/31 Vue.js
[00:35]可解锁地面特效
2018/12/20 DOTA
Python访问纯真IP数据库脚本分享
2015/06/29 Python
浅谈Python中带_的变量或函数命名
2017/12/04 Python
Python中getpass模块无回显输入源码解析
2018/01/11 Python
在windows下Python打印彩色字体的方法
2018/05/15 Python
Python用于学习重要算法的模块pygorithm实例浅析
2018/08/16 Python
Python socket实现多对多全双工通信的方法
2019/02/13 Python
python 返回一个列表中第二大的数方法
2019/07/09 Python
OpenCV模板匹配matchTemplate的实现
2019/10/18 Python
Python使用pyexecjs代码案例解析
2020/07/13 Python
LocalStorage记住用户和密码功能
2017/07/24 HTML / CSS
Jacadi Paris美国官方网站:法国童装品牌
2017/10/15 全球购物
机械个人求职信范文
2014/01/24 职场文书
优秀学生干部推荐材料
2014/02/03 职场文书
消防战士优秀事迹材料
2014/02/13 职场文书
《金钱的魔力》教学反思
2014/02/24 职场文书
解除聘用合同证明书范本
2014/09/11 职场文书
教师批评与自我批评
2014/10/15 职场文书
欠条范文
2015/07/03 职场文书
Golang生成Excel文档的方法步骤
2021/06/09 Golang
nginx中封禁ip和允许内网ip访问的实现示例
2022/03/17 Servers