资讯专栏INFORMATION COLUMN

关于跨域

AlexTuan / 12952人阅读

摘要:服务端接收到请求后,通过该参数获得回调函数名,并将数据放在参数中将其返回收到结果后因为是标签,所以浏览器会当做是脚本进行运行,从而达到跨域获取数据的目的。

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

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

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

Ajax 的便利性大家都清楚,可以在不向服务器提交完整的页面的情况下,实现局部更新页面。但是浏览器处于对安全方面的考虑,不允许跨域调用其他页面的对象。
其实这个也不能怪浏览器,假设谁都可以随随便便向你发送请求,那样有很大的安全隐患。
根据浏览器的同源策略, 只有当协议,域名,端口相同的时候才算是同源, 反之则均视为是一个跨域的请求.
也就是说我刚刚的Vue端口是8081,服务端端口是8080,端口不一样,因为同源策略的存在 ,所有我的请求会失败。

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

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

JSONP

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

首先前端先设置好回调函数,并将其作为 url 的参数。

服务端接收到请求后,通过该参数获得回调函数名,并将数据放在参数中将其返回

收到结果后因为是 script 标签,所以浏览器会当做是3脚本进行运行,从而达到跨域获取数据的目的。

我的前端是index.html,后端是server.js
后端逻辑:

//server.js
const 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这种方法跨域,他的兼容性很好,可以在古老的浏览器中国使用,因为这种方法是利用了

这次前端启动需要使用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

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

假设有这样的一个场景,你的页面需要获取 CNode:Node.js专业中文社区 论坛上一些数据,如通过 https://cnodejs.org/api/v1/topics,当时因为不同域,所以你可以将请求后端,让其对该请求代为转发。

后端代码如下:

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");

前端代码:


这样就成功了

总结

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

JSONP

优点是可以兼容老浏览器,缺点是只能发送GET请求

CORS

优点简单方便,支持post请求,缺点是需要后端的配合,不支持老版浏览器。。

Server Proxy

优点是前端正常发送ajax请求,缺点是后端会二次请求。

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

参考资料:

跨域资源共享 CORS 详解[阮一峰的博客]:http://www.ruanyifeng.com/blo...

关于跨域,你想知道的全在这里:https://zhuanlan.zhihu.com/p/...

不要再问我跨域的问题了[sf]:https://segmentfault.com/a/11...

关于跨域,以及跨域的几种方式[cnblog]:https://www.cnblogs.com/chens...

浏览器的同源策略[MDN]:https://developer.mozilla.org...

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/102557.html

相关文章

  • 20K前端大佬面试(关于如何回答ajax跨域问题)

    摘要:在接触前端开发起,跨域这个词就一直以很高的频率在我们学习工作中重复出现,最近在工作中遇到了跨域的相关问题,这里我把它总结记录一下。 在接触前端开发起,跨域这个词就一直以很高的频率在我们学习工作中重复出现,最近在工作中遇到了跨域的相关问题,这里我把它总结记录一下。关于跨域,有N种类型,现在我只专注于ajax请求跨域(ajax跨域只是属于浏览器同源策略中的一部分,其它的这里不做介绍),内容...

    Yangyang 评论0 收藏0
  • 关于跨域

    摘要:经历了几场笔试面试,屡次被问到关于如何实现跨域。转自个人博客关于跨域什么是跨域一般来说,如果你在开发中需要进行跨域操作从一个非同源网站发送请求获取数据,一般而言,你在浏览器控制台看到的结果为同源策略说到跨域就不得不提同源策略。 前言 转眼就是秋招季啦。经历了几场笔试面试,屡次被问到关于如何实现跨域。老实说,之前都是纸上谈兵,也没有项目需要跨域,甚至觉得这个东西没什么意义。直到今天项目中...

    CoreDump 评论0 收藏0
  • 关于跨域踩的坑,浏览器 status code为200,但实际上是跨域

    摘要:背景后端使用并更改本地文件,起本地服务。使用调用后端接口,要求为格式,并要求在里加一些内容。借用凝雨关于跨域踩坑经验总结 背景 后端使用Nginx并更改本地host文件,起本地服务。将aaa.bbbb.com代理至本地IP地址(10.26.36.156)。使用$.ajax调用后端restful接口,要求content-type为application/json格式,并要求在reques...

    neu 评论0 收藏0
  • 关于vue-resource在dev环境下跨域问题的解决方法

    摘要:跨域问题相信跨域问题是每个前端在请求中都会遇到的问题因为浏览器的同源策略的限制所以是不支持跨域的当然当后台在没有完成搭建的时候这时候我们需要使用到模拟数据的时候这时候很多的就会出现跨域问题在中当然这个问题也不例外如下所以在此我也就整理出了 跨域问题 相信跨域问题是每个前端在ajax请求中都会遇到的问题,因为浏览器的同源策略的限制,所以ajax是不支持跨域的,当然当后台在没有完成搭建的...

    timger 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<