博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
关于跨域
阅读量:6988 次
发布时间:2019-06-27

本文共 3282 字,大约阅读时间需要 10 分钟。

在使用Vue搭建的一个后端管理系统中,我使用axios请求本地的Node环境下的接口,但是请求失败,然后我错误信息是:

大概意思就是不能访问
http://localhost:8080 我的Vue项目端口是
http://localhost:8081,Node服务端运行在
http://localhost:8080端口上,也就是说因为请求端口和响应端口不一致,所以请求失败。 我也在网上查看了一些关于跨域出现的原因及解决的方法,并记录下来。

为什么会有跨域

跨域一句话的理解就是:服务端和请求端的地址不一样。

什么是跨域

Ajax 的便利性大家都清楚,可以在不向服务器提交完整的页面的情况下,实现局部更新页面。但是浏览器处于对安全方面的考虑,不允许跨域调用其他页面的对象。

其实这个也不能怪浏览器,假设谁都可以随随便便向你发送请求,那样有很大的安全隐患。
根据浏览器的同源策略, 只有当协议,域名,端口相同的时候才算是同源, 反之则均视为是一个跨域的请求.
也就是说我刚刚的Vue端口是8081,服务端端口是8080,端口不一样,因为同源策略的存在 ,所有我的请求会失败。

一个问题,当找到了原因,这个问题就解决了一半了。

怎么解决跨域

下面就先介绍三种跨全域的方法:

JSONP

应该是最常见解决跨域的方法了, 他为什么能解决跨域呢,是因为Web 页面上调用 js 文件不受浏览器同源策略的影响,所以通过 Script 便签可以进行跨域的请求:

  1. 首先前端先设置好回调函数,并将其作为 url 的参数。
  2. 服务端接收到请求后,通过该参数获得回调函数名,并将数据放在参数中将其返回
  3. 收到结果后因为是 script 标签,所以浏览器会当做是3脚本进行运行,从而达到跨域获取数据的目的。 我的前端是index.html,后端是server.js 后端逻辑:
//server.jsconst url = require('url');const http = require('http');http.createServer((req, res)=>{const data = {    x: 10//返回的数据};const callback = url.parse(req.url, true).query.callback;res.writeHead(200);res.end(`${callback}(${JSON.stringify(data)})`);//执行回调函数,返回data}).listen(3000, 'localhost');console.log('启动服务,监听 localhost:3000');复制代码

然后使用node server.js运行 前端:

//index.html        复制代码

之后打开index.html;就可以在控制台看到返回的数据了:

至此,通过 JSONP 跨域获取数据已经成功了,jsonp这种方法跨域,他的兼容性很好,可以在古老的浏览器中国使用,因为这种方法是利用了<script>标签的特殊性,所有只支持GET请求。

CORS

CORS 是一个 W3C 标准,全称是"跨域资源共享"(Cross-origin resource sharing)它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了 ajax 只能同源使用的限制。

CORS 需要浏览器和服务器同时支持才可以生效,对于开发者来说,CORS 通信与同源的 ajax 通信没有差别,代码完全一样。浏览器一旦发现 ajax 请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。

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

前端:

复制代码

这次前端启动需要使用node-server来启动,使用npm install node-server下载,然后当前目录下使用node-server就可以了 后端:

const http = require('http');http.createServer((req, res)=>{const data = {    'data': 'Hello world'//返回的数据};res.writeHead(200, {
'Access-Control-Allow-Origin': 'http://127.0.0.1:8080'});//设置的头部信息需要和前端请求的地址一致res.end(JSON.stringify(data));//返回data}).listen(3000, '127.0.0.1');console.log('启动服务,监听 127.0.0.1:3000');复制代码

使用命令node server.js启动;

CORS与JSONP的使用目的相同,但是比JSONP更强大。

JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。

Server Proxy

服务器代理,顾名思义,当你需要有跨域的请求操作时发送请求给后端,让后端帮你代为请求,然后最后将获取的结果发送给你。

假设有这样的一个场景,你的页面需要获取  论坛上一些数据,如通过 ,当时因为不同域,所以你可以将请求后端,让其对该请求代为转发。

后端代码如下:

const url = require('url');const http = require('http');const https = require('https');http.createServer((req, res)=>{const path = url.parse(req.url).path.slice(1);//核对请求路由是否一致if(path === 'topics'){    https.get('https://cnodejs.org/api/v1/topics', (resp)=>{        //https代发请求        let data='';        resp.on('data', chunk=>{            data+= chunk        });        resp.on('end', ()=>{            res.writeHead(                200,                {
'Content-Type': 'application/json; charset=utf-8'} ); res.end(data); //返回数据 }) })}}).listen(3000, '127.0.0.1');console.log('启动服务,监听 127.0.0.1:3000');复制代码

前端代码:

复制代码

这样就成功了

总结

常用的跨域方式基本就是这三种:

  1. JSONP 优点是可以兼容老浏览器,缺点是只能发送GET请求
  2. CORS 优点简单方便,支持post请求,缺点是需要后端的配合,不支持老版浏览器。。
  3. Server Proxy 优点是前端正常发送ajax请求,缺点是后端会二次请求。

其他的跨域方式还有:location.hashwindow.namepostMessage等方式,有时间也可以了解一下。

参考资料:

  • 跨域资源共享 CORS 详解[阮一峰的博客]:
  • 关于跨域,你想知道的全在这里:
  • 不要再问我跨域的问题了[sf]:
  • 关于跨域,以及跨域的几种方式[cnblog]:
  • 浏览器的同源策略[MDN]:

转载于:https://juejin.im/post/5c8b67f6f265da2dd2191308

你可能感兴趣的文章
iOS之传值
查看>>
探索webpack热更新对代码打包结果的影响(二)
查看>>
pandas 修改 DataFrame 列名
查看>>
《2018年云上挖矿态势分析报告》发布,非Web类应用安全风险需重点关注
查看>>
leetcode409.Longest Palindrome
查看>>
Nervos 双周报第 3 期:佛系新年之后的开工大吉!
查看>>
【PHP 扩展开发】Zephir 基础篇
查看>>
字节跳动开源Go结构体标签表达式解释器,成请求参数校验的杀手锏
查看>>
怎么将在线录制的视频转为GIF动态图
查看>>
【剑指offer】顺时针打印矩阵
查看>>
leetcode讲解--861. Score After Flipping Matrix
查看>>
聊聊JavaScript和Scala的表达式 Expression
查看>>
[原]数据科学教程: 如何使用 mlflow 管理数据科学工作流
查看>>
JAVA 8 函数式接口--Supplier
查看>>
Dockerfile多阶段构建原理和使用场景
查看>>
七牛云赵之健:多维度融合赋能视频 AI 的实践
查看>>
CSS3中的box-sizing
查看>>
云计算新风向:多云战略优化企业云支出
查看>>
Windows改Linux(一),新建Ubuntu虚拟机小白向导
查看>>
HTML5调用手机前置摄像头或后置摄像头拍照,canvas显示,经过Android测试
查看>>