详解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 相关文章推荐
神奇的7个jQuery 3D插件整理
Jan 06 Javascript
ie下$.getJSON出现问题的解决方法
Feb 12 Javascript
JavaScript中的apply和call函数详解
Jul 20 Javascript
javascript实现全角半角检测的方法
Jul 23 Javascript
JavaScript实现的伸展收缩型菜单代码
Oct 14 Javascript
深入理解关于javascript中apply()和call()方法的区别
Apr 12 Javascript
javascript执行环境及作用域详解
May 05 Javascript
Node.js使用NodeMailer发送邮件实例代码
Mar 06 Javascript
ionic2打包android时gradle无法下载的解决方法
Apr 05 Javascript
vue.js element-ui validate中代码不执行问题解决方法
Dec 18 Javascript
vue实现axios图片上传功能
Aug 20 Javascript
ES6 Iterator遍历器原理,应用场景及相关常用知识拓展详解
Feb 15 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解析目录路径的3个函数总结
2014/11/18 PHP
ThinkPHP实现附件上传功能
2017/04/27 PHP
PHP使用Nginx实现反向代理
2017/09/20 PHP
php实现的PDO异常处理操作分析
2018/12/27 PHP
php 使用expat方式解析xml文件操作示例
2019/11/26 PHP
javascript replace()正则替换实现代码
2010/02/26 Javascript
javaScript使用EL表达式的几种方式
2014/05/27 Javascript
基于jQuery的select下拉框选择触发事件实例分析
2016/11/18 Javascript
10道典型的JavaScript面试题
2017/03/22 Javascript
JS获取鼠标坐标并且根据鼠标位置不同弹出不同内容
2017/06/12 Javascript
图片加载完成再执行事件的实例
2017/11/16 Javascript
详解vue-cli 快速搭建单页应用之遇到的问题及解决办法
2018/03/01 Javascript
vue中导出Excel表格的实现代码
2018/10/18 Javascript
JavaScript动画实例之粒子文本的实现方法详解
2020/07/28 Javascript
JavaScript实现消消乐的源代码
2021/01/12 Javascript
原生js实现放大镜组件
2021/01/22 Javascript
Django中实现点击图片链接强制直接下载的方法
2015/05/14 Python
Python保存MongoDB上的文件到本地的方法
2016/03/16 Python
OpenCV2.3.1+Python2.7.3+Numpy等的配置解析
2018/01/05 Python
Python中文件的读取和写入操作
2018/04/27 Python
Python matplotlib的使用并自定义colormap的方法
2018/12/13 Python
Tornado实现多进程/多线程的HTTP服务详解
2019/07/25 Python
pycharm 安装JPype的教程
2019/08/08 Python
python3 使用Opencv打开USB摄像头,配置1080P分辨率的操作
2019/12/11 Python
python如何实现不可变字典inmutabledict
2020/01/08 Python
Windows下Anaconda安装、换源与更新的方法
2020/04/17 Python
Python 删除List元素的三种方法remove、pop、del
2020/11/16 Python
python爬虫工具例举说明
2020/11/30 Python
python实现PolynomialFeatures多项式的方法
2021/01/06 Python
链表面试题-一个链表的结点结构
2015/05/04 面试题
公司年终奖分配方案
2014/06/16 职场文书
市级三好学生事迹材料
2014/08/27 职场文书
2014年手术室工作总结
2014/11/26 职场文书
2014年审计人员工作总结
2014/12/19 职场文书
总经理岗位职责范本
2015/04/01 职场文书
golang import自定义包方式
2021/04/29 Golang