详解vue-cli项目中的proxyTable跨域问题小结


Posted in Javascript onFebruary 09, 2018

什么是跨域?

同源策略规定了如果两个 url 的协议、域名、端口中有任何一个不等,就认定它们跨源了。

跨域的解决方式有哪几种?

1.JSONP 是 JSON with padding(填充式 JSON 或参数式 JSON)的简写。

JSONP实现跨域请求的原理简单的说,就是动态创建<script>标签,然后利用<script>的src 不受同源策略约束来跨域获取数据。

JSONP 由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调函数的名字一般是在请求中指定的。而数据就是传入回调函数中的 JSON 数据。
动态创建<script>标签,设置其src,回调函数在src中设置:

var script = document.createElement("script");
script.src = "https://api.douban.com/v2/book/search?q=javascript&count=1&callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);

在页面中,返回的JSON作为参数传入回调函数中,我们通过回调函数来来操作数据。

function handleResponse(response){
  // 对response数据进行操作代码
  console.log(response)
}

JSONP目前还是比较流行的跨域方式,虽然JSONP使用起来方便,但是也存在一些问题:

首先, JSONP 是从其他域中加载代码执行。如果其他域不安全,很可能会在响应中夹带一些恶意代码,而此时除了完全放弃 JSONP 调用之外,没有办法追究。因此在使用不是你自己运维的 Web 服务时,一定得保证它安全可靠。

JSONP 具有直接访问响应文本的优点,但是要想确认 JSONP 是否请求失败并不容易,因为 script 标签的 onerror 事件还未得到浏览器广泛的支持,此外它仅能支持 GET 方式调用。

2.cros跨域

整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

一个常用的完整的跨域头:

let express=require("express");
let app=express();
app.use(function(req,res,next){
 //如果在webpack里配置了代理,那么这些响应头都不要了
 //只允许8080访问
  res.header('Access-Control-Allow-Origin','http://localhost:8080');

 //服务允许客户端发的方法
 res.header('Access-Control-Allow-Methods','GET,POST,DELETE,PUT');
 //服务器允许的请求头
 res.header('Access-Control-Allow-Headers','Content-Type,Accept');
 //跨域携带cookie 允许客户端把cookie发过来
 res.header('Access-Control-Allow-Credentials','true');
 //如果请求的方法是OPTIONS,那么意味着客户端只要响应头,直接结束响应即可
 if(req.method == 'OPTIONS'){
  res.end();
 }else{
  next();
 }
});
app.listen(3000);

3.hash + iframe

4.postMessage

5.WebSockets

后台只给我接口,不能修改后台,怎么跨域?

详解vue-cli项目中的proxyTable跨域问题小结

在实际工作中,前后端配合并不是那么默契,如果后台只给我接口,不能修改后台,怎么跨域?
在vue项目和react项目中的config文件中,都有一个proxy代理设置,这个就是用来在开发环境下进行跨域的。对其进行设置就能实现跨域。

通过vue-cli脚手架搭建出来的项目,修改config文件夹下的index.js中的proxyTable就能实现:

详解vue-cli项目中的proxyTable跨域问题小结

module.exports = {
 dev: {
  env: {
   NODE_ENV: '"development"'
  },
  //proxy

  // 只能在开发环境中进行跨域,上线了要进行反向代理nginx设置
   proxyTable: {
    //这里理解成用‘/api'代替target里面的地址,后面组件中我们掉接口时直接用api代替 比如我要调用'http://40.00.100.100:3002/user/add',直接写‘/api/user/add'即可
   '/api': {
     target: 'http://news.baidu.com',//你要跨域的网址 比如 'http://news.baidu.com',
    secure: true, // 如果是https接口,需要配置这个参数
    changeOrigin: true,//这个参数是用来回避跨站问题的,配置完之后发请求时会自动修改http header里面的host,但是不会修改别的
    pathRewrite: {
     '^/api': '/api'//路径的替换规则
     //这里的配置是正则表达式,以/api开头的将会被用用‘/api'替换掉,假如后台文档的接口是 /api/list/xxx
     //前端api接口写:axios.get('/api/list/xxx') , 被处理之后实际访问的是:http://news.baidu.com/api/list/xxx
    }
   }
  },

让我们用本地起的服务来测试一下如何跨域 demo

0.用vue-cli搭建的脚手架,npm run dev 前端端口号一般是:http://localhost:8080

1.修改config文件中的index.js proxyTable:{}这段代码,替换掉即可:

module.exports = {
 dev: { 
   proxyTable: {
   '/api': {
     target: 'http://localhost:8000',
    secure: true,  
    changeOrigin: true,
    pathRewrite: {
     '^/api': '/api'
    }
   }
  },

2.自己写一个后台,使用express+node.js ,不设置任何跨域头,代码如下:

注意自己需要在当前文件夹下提前准备一个list.json的文件,用来读取数据,返回数据。fs.readFile('./list.json','utf8',cb)

详解vue-cli项目中的proxyTable跨域问题小结

let express = require('express');
let app = express();
let fs = require('fs');
let list = require('./list');
let bodyParser = require('body-parser');
app.use(bodyParser.json());
app.use(express.static(__dirname));

//read
function read(cb) { //用来读取数据的,注意自己在mock文件夹下准备一些数据
 fs.readFile('./list.json','utf8',function (err,data) {
  if(err || data.length === 0){
   cb([]); // 如果有错误 或者文件没长度 就是空数组
  }else{
   cb(JSON.parse(data)); // 将读出来的内容转化成对象
  }
 })
}
//write
function write(data,cb) { // 写入内容
 fs.writeFile('./list.json',JSON.stringify(data),cb)
}
// 注意 没有设置跨域头
app.get('/api/list',function (req,res) {
 res.json(list);
});
app.listen(8000,()=>{
 console.log('8000 is ok');
});

3.前端调取的api代码:

import axios from 'axios';
 axios.interceptors.response.use((res)=>{
 return res.data; // 在这里统一拦截结果 把结果处理成res.data
});
export function getLists() {
  return axios.get('/api/list');
}

4.在组件中进行跨域调取接口,打印数据

随便在一个文件中引入api测试一下 打印出来接口返回的数据

import {getLists} from '../../api/index'
 export default {
  async created(){
   let dataList=await getLists();
   console.log(dataList,"我请求的数据");
  },

5.查看控制台,打印出数据,没有保错,代表跨域成功,代理服务成功

详解vue-cli项目中的proxyTable跨域问题小结

详解vue-cli项目中的proxyTable跨域问题小结

开发环境成功跨域了,上线怎么办?

上线要进行nginx反向代理设置,同时应区分环境变量,具体设置请看图片:

详解vue-cli项目中的proxyTable跨域问题小结

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS input文本框禁用右键和复制粘贴功能的代码
Apr 15 Javascript
AlertBox 弹出层信息提示框效果实现步骤
Oct 11 Javascript
jQuery.event兼容各浏览器的event详细解析
Dec 18 Javascript
js+html5获取用户地理位置信息并在Google地图上显示的方法
Jun 05 Javascript
Vuejs第九篇之组件作用域及props数据传递实例详解
Sep 05 Javascript
BootStrap下拉菜单和滚动监听插件实现代码
Sep 26 Javascript
JavaScript中的普通函数和箭头函数的区别和用法详解
Mar 21 Javascript
Vue.js学习笔记之常用模板语法详解
Jul 25 Javascript
vue 封装自定义组件之tabal列表编辑单元格组件实例代码
Sep 07 Javascript
jQuery图片加载失败替换默认图片方法汇总
Nov 29 jQuery
JS实现选项卡效果的代码实例
May 20 Javascript
微信小程序8种数据通信的方式小结
Feb 03 Javascript
使用express搭建一个简单的查询服务器的方法
Feb 09 #Javascript
js自定义trim函数实现删除两端空格功能
Feb 09 #Javascript
JavaScript运行原理分析
Feb 09 #Javascript
vue 全选与反选的实现方法(无Bug 新手看过来)
Feb 09 #Javascript
详解如何在项目中使用jest测试react native组件
Feb 09 #Javascript
vue checkbox 全选 数据的绑定及获取和计算方法
Feb 09 #Javascript
mint-ui 时间插件使用及获取选择值的方法
Feb 09 #Javascript
You might like
PHP中的cookie
2006/11/26 PHP
一篇不错的PHP基础学习笔记
2007/03/18 PHP
MySql 按时间段查询数据方法(实例说明)
2008/11/02 PHP
PHP简单读取PDF页数的实现方法
2016/07/21 PHP
PHP集成环境XAMPP的安装与配置
2018/11/13 PHP
Laravel模糊查询区分大小写的实例
2019/09/29 PHP
对字符串进行HTML编码和解码的JavaScript函数
2010/02/01 Javascript
根据表格中的某一列进行排序的javascript代码
2013/11/29 Javascript
jQuery调取jSon数据并展示的方法
2015/01/29 Javascript
wangEditor编辑器失去焦点后仍然可以在原位置插入图片分析
2015/05/06 Javascript
jQuery实现的鼠标滑过弹出放大图片特效
2016/01/08 Javascript
第二次聊一聊JS require.js模块化工具的基础知识
2016/04/17 Javascript
移动端js触摸事件详解
2016/09/18 Javascript
AngularJS自定义插件实现网站用户引导功能示例
2016/11/07 Javascript
js 点击a标签 获取a的自定义属性方法
2016/11/21 Javascript
springmvc接收jquery提交的数组数据代码分享
2017/10/28 jQuery
JS将网址url转化为JSON格式的方法
2018/07/02 Javascript
支付宝小程序自定义弹窗dialog插件的实现代码
2018/11/30 Javascript
jquery实现简单每周轮换的日历
2020/09/10 jQuery
如何在JavaScript中等分数组的实现
2020/12/13 Javascript
[02:42]完美大师赛主赛事淘汰赛第三日观众采访
2017/11/25 DOTA
python内置函数:lambda、map、filter简单介绍
2017/11/16 Python
基于Django的ModelForm组件(详解)
2017/12/07 Python
Python实现图片批量加入水印代码实例
2019/11/30 Python
Python绘制三角函数图(sin\cos\tan)并标注特定范围的例子
2019/12/04 Python
python3 tcp的粘包现象和解决办法解析
2019/12/09 Python
Pytorch 使用opnecv读入图像由HWC转为BCHW格式方式
2020/06/02 Python
手把手教你将Flask应用封装成Docker服务的实现
2020/08/19 Python
详解Python爬虫爬取博客园问题列表所有的问题
2021/01/18 Python
联想墨西哥官方网站:Lenovo墨西哥
2016/08/17 全球购物
大学生毕业求职的自我评价
2013/09/29 职场文书
信息技术专业大学生个人的自我评价
2013/10/05 职场文书
六一儿童节活动策划方案
2014/01/27 职场文书
黄河绝恋观后感
2015/06/08 职场文书
银行岗位培训心得体会
2016/01/09 职场文书
Python爬虫之爬取最新更新的小说网站
2021/05/06 Python