前端跨域问题解决方案

背景:

同源策略:NetSpace公司引入,基于浏览器安全,防止浏览器收到XSS、CSFR等攻击。同源,即协议+域名+端口完全一致。

同源策略限制的行为:
Cookie、LocalStorage和IndexDB无法读取
DOM和JS对象无法获取
Ajax请求不能发送

解决方案:
方案一:JSONP
原理:通过script标签引入的js不受同源策略的限制,而XmlHttpRequest对象受到同源策略的影响。可以加载跨域服务器上的脚本,用JSONP获取的不是JSON数据,而是可以直接运行的JS脚本。
eg1:jquery

function jsonpCallback(data) {
console.log("jsonpCallback: " + data.name)
}
$.ajax({
url:"http://www.nanhuaqiushui.com:8080/login",
type:"get",
dataType:"jsonp",

data:{
    name: $("#name").val(),
    id: $("#id").val()
},
cache: false,
timeout: 5000,
jsonp: "callback",          //jsonp字段含义为服务器通过什么字段获取回调函数的名称
jsonpCallback:"jsonpCallback",    //自定义回调函数名
success:function(data){
    console.log("ajax success callback: " + data.name);
},
error: function(jqXHR, textStatus, errorThrown){
    console.log(textStatus + ' ' + errorThrown);
}

})

eg2:vue
this.$http.jsonp("http://www.nanhuaqiushui.com:8080/login",{
params:{
name: $("#name").val(),
id: $("#id").val()
},
jsonp: "jsonpCallback"
}).then((res) => {
console.log(res);
});

服务器端处理:

app.get("/login", function(req,res){
console.log("server accept: " + req.query.name, req.query.id);
var data = "{" + "name:" + req.query.name + "- server 3001 process" + "," + "id:" + req.query.id + "- server 3001 process" + "}";
var callback = req.query.callback;
var jsonp = callback + "(" + data + ")";
console.log(jsonp);
res.send(jsonp);
res.end();
});

注意:data中字符串拼接,不能直接将JSON格式的data直接传给回调函数,否则会发生编译错误。
本质:

不足:
1.只能使用GET请求(即时POST也会被转换成GET请求)。
2.JSONP本质上是通过script标签的src属性实现跨域请求的,而非ajax,因此不是通过XMLHttpRequest进行传输的,所以无法注册success、error等事件监听函数。

方案二:CORS(跨资源共享)实现跨域调用
原理:使用自定义的HTTP头部让浏览器与服务器沟通,从而决定请求或响应是否成功。
Cross-Origin Resource Sharing(CORS)跨域资源共享是一份浏览器技术的规范,提供了Web服务从不同域传来沙盒脚本的方法,以避开浏览器的同源策略。(现代浏览器都支持CORS)
优点:采用XMLHttpRequest对象传递,同时支持GET/POST等多种请求方式,方便调试。是JSONP模式的现代版。

eg:

app.post(‘/cors‘,function(req,res){
res.header("Access-Control-Allow-Origin","*"); //设置请求来源不受限制
res.header("Access-Control-Allow-Headers","X-Requested-With");
res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");
res.header("Content-Type", "application/json;charset=utf-8");
var data = {
name: req.body.name + ‘ - server 3001 cors process‘,
id: req.body.id + ‘ - server 3001 cors process‘
};
res.send(data);
res.end();
})
优点:只需服务端设置Access-Control-Allow-Origin即可,前端无需设置。
withCredentials: true // 前端设置是否带cookie

方案三:window.name + iframe
原理:window对象的name属性很特别,name值在不同的页面(甚至不同域名)加载后依旧存在,而且可以支持非常长的name值(2MB)。

var proxy = function(url, callback){
var state = 0;
var iframe = document.createElement("iframe");
//加载跨域页面
iframe.src = url;
iframe.onload = function(){
if(state == 0){
//第一次onload(跨域页)成功后,切换到同域代理页面
iframe.contentWindow.location = "http://www.nanhuaqiushui.com";
state = 1;
}else if(state == 1){
//第二次onload(同域proxy页)成功后,读取同域window.name中数据
callback(iframe.contentWindow.name);
destroyFrame();
}
}
}

documetn.body.appendChild(iframe);

//获取数据后销毁这个iframe,释放内存

function destroyFrame(){
iframe.contentWindow.document.write("");
iframe.contentWindow.close();
document.body.removeChild(iframe);
}

//请求跨域b页面数据

proxy("http://www.domain2.com/b.html",function(data){
alert(data);
});

方案四:postMessage跨域
postMessage是H5 中新的api,可解决以下问题:
页面和其打开的新窗口的数据传递;
多窗口之间消息传递;
页面与嵌套的iframe消息传递;
上面三个场景的跨域数据传递。

用法:postMessage(data,origin)

方法五:document.domain(两个iframe之间)
背景:同源策略认为域和子域隶属于不同的域,因此会被浏览器拦截。
方法:把它们的domain设置为相同的域
问题:安全性,当一个站点被攻击后,另一个站点也会引起安全漏洞;
如果一个页面中引入多个iframe,要想跨域访问,就要都设置为相同的domain值

方法六:ngix代理跨域
1.ngix配置解决iconfont跨域
背景:浏览器跨域访问js\css\img等常规静态资源被同源策略许可,但是iconfont字体文件(eot|otf|ttf|woff|svg)例外,此时需在ngix的静态资源服务器中加入配置:;
location / {
add_header Access-Control-Allow-Origin * ;
}
2.ngix反向代理接口跨域
原理:同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也就不存在跨域问题。
实现思路:通过ngix配置一个代理服务器(域名与domain1相同,端口不同)做跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中domain信息,方便当前与cookie写入,实现跨域登录。

方案七:WebSocket协议跨域
WebSocket protocol是HTML5一种新的协议。它实现了浏览器与服务器全双工通信,同时允许跨域通讯,是server push技术的一种很好的实现。原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。

前端:

user input:

node后台:

var http = require(‘http‘);
var socket = require(‘socket.io‘);

// 启http服务
var server = http.createServer(function(req, res) {
res.writeHead(200, {
‘Content-type‘: ‘text/html‘
});
res.end();
});

server.listen(‘8080‘);
console.log(‘Server is running at port 8080...‘);

// 监听socket连接
socket.listen(server).on(‘connection‘, function(client) {
// 接收信息
client.on(‘message‘, function(msg) {
client.send(‘hello:‘ + msg);
console.log(‘data from client: ---> ‘ + msg);
});

// 断开处理
client.on('disconnect', function() {
    console.log('Client socket has closed.');
});

});

原文地址:https://www.cnblogs.com/nanhuaqiushui/p/10493478.html

时间: 2024-10-09 00:17:59

前端跨域问题解决方案的相关文章

前端跨域问题的几种解决方案

前端跨域问题 一:同源策略 1.what's this 所谓同源是指,域名,协议,端口相同.当浏览器运行一个JS脚本时会进行同源检测,如果不同源是不能执行的. 2.源继承 来自about:blank,javascript:和data:URLs中的内容,继承了将其载入的文档所指定的源,因为它们的URL本身未指定任何关于自身源的信息. 3.变更源 变更源可以实现基础域相同的不同页面的跨域问题. 如:a.baidu.com/index.html 通过 iframe 引入 b.baidu.com/ind

html5的postmessage实现js前端跨域访问及调用解决方案

关于跨域访问,使用JSONP的方法,我前面已经demo过了,具体见http://supercharles888.blog.51cto.com/609344/856886,HTML5提供了一个非常强大的API,叫postMessage,它其实就是以前iframe的进化版本,使用起来极其方便,这里举个实验例子: 我们依旧按照与上文相同的设定,假定我们有2个Domain Domain1: http://localhost:8080  它上面有个应用叫HTMLDomain1,并且有个页面叫sender.

前端跨域访问

1. JSONP 2. CORS(Cross-origin resource sharing) 2.1 运行模式 2.2 JQuery支持CORS 2.3 与JSONP相比 3. 跨域访问在点评的应用 References 在互联网应用中: 一个页面需要请求多个域名下的web服务端接口 同时一个web服务接口可能会被很多不同域名下的页面请求. 一个web应用如果支持为了支持以上模式而申请多个域名是不合算的,因为域名申请和管理所占用的资源比较大,因此服务端支持跨域就成了一个更合理的解决方案.解决跨

angularjs跨域post解决方案

转自:http://www.thinksaas.cn/topics/0/34/34536.html 前端同学李雷和后台同学韩梅梅分别在自己电脑上进行开发,后台接口写好的时候,李雷改动完就把前端代码上传到gitlab,然后在测试机上从gitlab上拉下来,然后在测试机上移动最新代码,最后回到本机刷新页面.有时候碰到网速不好的情况传个git传了半天,或者李雷刚上传完发现少写了一个单词,加上再传上一看尼玛单词又写错了.对于实时需要改动代码的李雷同学而言 另外一种方案是李雷和韩梅梅分别在自己电脑上进行开

跨域请求解决方案

在前端开发过程中,难免和服务端产生数据交互.一般情况我们的请求分为这么几种情况: 只关注发送,不关注接收 不仅要发送,还要关注服务端返回的信息 同域请求 跨域请求 上面提到了一个概念,我们这里简单做一下讲解.什么叫做跨域?一般情况下,跨域分为三种情况:跨协议.跨子域.跨域名.下面距离梳理一下这三种情况. 跨协议:比如说我现在的域名地址是http://www.12306.cn,有一些请求需要发送到https://www.12306.cn,此时这个请求相对与http://www.12306.cn来说

浏览器跨域访问解决方案

浏览器跨域访问解决方案 2015年11月4日 18972次浏览 跨域的概念 跨域大家都知道,不同地址,不同端口,不同级别,不同协议都会构成跨域.例如:about.haorooms.com和www.haorooms.com都会构成跨域.总结起来只要协议.域名.端口有任何一个不同,都被当作是不同的域.下面举例,每两个一组. URL 说明 是否允许通信 http://www.haorooms.com/a.js http://www.haorooms.com/b.js 同一域名下 允许 http://w

.net 访问 geoserver 发布的 wms   跨域问题解决方案

环境:  服务器  geoserver2.4.1 开发机访问服务器发布的wms 存在跨域问题,研究两天终于找到解决方案. 主要思路是: 使用jquery的ajax 代替Groserver的request, 然后将wms的请求地址转发到.net的处理程序, 使用.net的处理程序进行跨域处理.  function mouseClick(e) {             var layer = new Array();             layer = map.getLayersByName(

解决前端跨域请求的几种方式

利用 JSONP 实现跨域调用 说道跨域调用,可能大家首先想到的或者听说过的就是 JSONP 了. 1.1 什么是JSONP JSONP 是 JSON 的一种使用模式,可以解决主流浏览器的跨域数据访问问题.其原理是根据 XmlHttpRequest 对象受到同源策略的影响,而 <script> 标签元素却不受同源策略影响,可以加载跨域服务器上的脚本,网页可以从其他来源动态产生 JSON 资料.用 JSONP 获取的不是 JSON 数据,而是可以直接运行的 JavaScript 语句. 1.2

前端跨域几种方式

跨域问题的直接原因是浏览器存在同源策略,浏览器同源指的是:两个页面的协议.端口和主机相同,则两个页面具有相同的源.IE下满足协议.主机相同,就认为是同源. 想象一下,如果没有同源策略,谁都可以修改你站点上的内容,读取你的cookie,后果难以想象 前端跨域的几种方式 修改document.domain document.domain 用来获取当前网页的域名,document.domain可以被赋值 document.domain只能修改成当前域名的主域名或者基础域名,如当前域名是b.360.cn