详解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去除空格的几种方法
Oct 03 Javascript
Hutia 的 JS 代码集
Oct 24 Javascript
js操作textarea方法集合封装(兼容IE,firefox)
Feb 22 Javascript
JavaScript简单实现鼠标拖动选择功能
Mar 06 Javascript
node.js操作mongoDB数据库示例分享
Nov 26 Javascript
JS 通过系统时间限定动态添加 select option的实例代码
Jun 09 Javascript
自制微信公众号一键排版工具
Sep 22 Javascript
基于vue.js中事件修饰符.self的用法(详解)
Feb 23 Javascript
Bootstrap Fileinput 4.4.7文件上传实例详解
Jul 25 Javascript
对于防止按钮重复点击的尝试详解
Apr 22 Javascript
Vue最新防抖方案(必看篇)
Oct 30 Javascript
Vue 监听元素前后变化值实例
Jul 29 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
操作Oracle的php类
2006/10/09 PHP
swfupload 多文件上传实现代码
2008/08/27 PHP
修改php.ini不生效问题解决方法(上传大于8M的文件)
2013/06/14 PHP
PHP基于工厂模式实现的计算器实例
2015/07/16 PHP
YII Framework框架教程之缓存用法详解
2016/03/14 PHP
PHP+Ajax实现的检测用户名功能简单示例
2019/02/12 PHP
javascript中使用css需要注意的地方小结
2010/09/01 Javascript
在IE 浏览器中使用 jquery的fadeIn() 效果 英文字符字体加粗
2011/06/02 Javascript
jquerymobile checkbox及时刷新才能获取其准确值
2012/04/14 Javascript
用JQuery在网页中实现分隔条功能的代码
2012/08/09 Javascript
js改变img标签的src属性在IE下没反应的解决方法
2013/07/23 Javascript
js 获取input点选按钮的值的方法
2014/04/14 Javascript
JQuery validate插件验证用户注册信息
2016/05/11 Javascript
Node.js刷新session过期时间的实现方法推荐
2016/05/18 Javascript
js中创建对象的几种方式
2017/02/05 Javascript
基于rem的移动端响应式适配方案(详解)
2017/07/07 Javascript
JS 判断某变量是否为某数组中的一个值的3种方法(总结)
2017/07/10 Javascript
Vue核心概念Getter的使用方法
2019/01/18 Javascript
移动端(微信等使用vConsole调试console的方法
2019/03/05 Javascript
JavaScript实现商品评价五星好评
2020/11/30 Javascript
JavaScript实现瀑布流布局的3种方式
2020/12/27 Javascript
[02:29]大剑、皮鞭、女装,这届DOTA2勇士令状里都有
2020/07/17 DOTA
python实现类似ftp传输文件的网络程序示例
2014/04/08 Python
Python列表和元组的定义与使用操作示例
2017/07/26 Python
Python实现最常见加密方式详解
2019/07/13 Python
用Pelican搭建一个极简静态博客系统过程解析
2019/08/22 Python
使用python批量转换文件编码为UTF-8的实现
2020/04/03 Python
django使用JWT保存用户登录信息
2020/04/22 Python
Python爬虫爬取百度搜索内容代码实例
2020/06/05 Python
英国领先的汽车轮胎和快速健康中心:Kwik Fit
2017/10/29 全球购物
《两个铁球同时着地》教学反思
2014/02/13 职场文书
求职信结尾怎么写
2014/05/26 职场文书
2015银行年终工作总结范文
2015/05/26 职场文书
纯 CSS 自定义多行省略的问题(从原理到实现)
2021/11/11 HTML / CSS
javascript之Object.assign()的痛点分析
2022/03/03 Javascript
vue项目proxyTable配置和部署服务器
2022/04/14 Vue.js