web前端的同学如果使用ajax,如果请求后端地址和页面访问的地址“URL的首部”不同就会出现访问被拒绝的情况,这就需要跨域来解决前后端的通讯问题,下面将列举一些在实际项目中应用也是比较多的方法。
服务器反向代理解决跨域
指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。 这里已nginx和node来实现如下:
//文件ngix.conf添加代码
location ~ /api {
//请求后端的地址
proxy_pass http://www.b.com:8080;
}
//node的代理如下
proxyTable: {
'/api': {
target: 'http://www.b.com:8080/',
changeOrigin: true,
//pathRewrite: {'^/api': '/'}是否重写
}
},
说明:如果页面url为http://www.a.com的页面需要ajax请求后端http://www.b.com:8080/api/dothis.do的地址。如果设置了反向代理,即可通过http://www.a.com/api/dothis.do来获取数据,就很好的解决了跨域问题的同时并未暴露后端地址给用户。
后端通过Access-Control-Allow-Origin来解决
Access-Control-Allow-Origin是html5中定义的一种解决资源跨域的策略。他是通过服务器端返回带有Access-Control-Allow-Origin标识的Response header,用来解决资源的跨域权限问题。
如果应许所有域名的访问,我们可以在header中设置Access-Control-Allow-Origin: * 。
如果应许部分域名访问,这里将已php为例子实现如下,这里将只应许前端URL为http://www.a.com才能访问:
$origin = isset($_SERVER['HTTP_ORIGIN'])? $_SERVER['HTTP_ORIGIN'] : '';
$allow_origin = array(
'http://www.a.com',
);
if(in_array($origin, $allow_origin)){
header('Access-Control-Allow-Origin:'.$origin);
}
jsonp解决get请求的跨域
json是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问。它的局限性主要是支持Get,
这里已php为例返回如下:
<?php
$data = array();//需要返回的数据
$callback = $_GET['callback'];
echo $callback.'('.json_encode($data).')';
exit;
?>
前端已jquery的ajax请求为例,它封装了jsonp的实现
$.ajax({
type : "get"//如果
url : "www.b.com:8080",
dataType : "jsonp",
jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名
success:function(json){},
error:function(){}
});
这里网上找了一篇原生JS的实现,代码如下:
function ajax(params) {
params = params || {};
params.data = params.data || {};
var json = params.jsonp ? jsonp(params) : json(params);
// jsonp请求
function jsonp(params) {
//创建script标签并加入到页面中
var callbackName = params.jsonp;
var head = document.getElementsByTagName('head')[0];
// 设置传递给后台的回调参数名
params.data['callback'] = callbackName;
var data = formatParams(params.data);
var script = document.createElement('script');
head.appendChild(script);
//创建jsonp回调函数
window[callbackName] = function(json) {
head.removeChild(script);
clearTimeout(script.timer);
window[callbackName] = null;
params.success && params.success(json);
};
//发送请求
script.src = params.url + '?' + data;
//为了得知此次请求是否成功,设置超时处理
if(params.time) {
script.timer = setTimeout(function() {
window[callbackName] = null;
head.removeChild(script);
params.error && params.error({
message: '超时'
});
}, time);
}
};
//格式化参数
function formatParams(data) {
var arr = [];
for(var name in data) {
arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
};
// 添加一个随机数,防止缓存
arr.push('v=' + random());
return arr.join('&');
}
// 获取随机数
function random() {
return Math.floor(Math.random() * 10000 + 500);
}
}
利用js动态创建一个link插入到文档中, 请求css文件,利用 computedStyle = window.getComputedStyle 获取指定元素的 style 对象,利用 computedStyle .content 获取内容
XMLHttpRequest对象(IE中为XMLHTTP对象)是AJAX应用的核心。由于现代浏览器对跨域请求的限制,在使用时需多加注意。本教程尽量用简单易懂的话描述(跨域)问题,并提供一个方案:通过Web代理(Web Proxy)
Jsonp原理是动态创建一个script标签,利用script标签src属性访问没有限制,实现跨域。Ajax是页面无刷新请求数据操作,Jsonp不是真正的ajax请求。讲解Ajax 和 jsonp的区别,在jquery中使用jsonp
JSONP方案:前端提供 API 的方法,其实解耦还没有解的很干净,我们在设置script的src时直接给它传参,后端插入这个参数这就可以了。因为JSONP是通过动态创建Script实现的,动态创建Script只有GET请求没有POST请求
浏览器的同源策略会导致跨域,这里同源策略又分为以下两种:DOM同源策略、XmlHttpRequest同源策略。只要协议、域名、端口有任何一个不同,都被当作是不同的域,之间的请求就是跨域操作。
在开发静态页面时,类似Vue的应用,我们常会调用一些接口,这些接口极可能是跨域,然后浏览器就会报cross-origin问题不给调。最简单的解决方法,就是把浏览器设为忽略安全问题,设置--disable-web-security。
此方案只能用于开发环境,线上最好设置同源策略(遇到个后端,装你妈批),前后端不在同一服务器的情况下,前端要访问后端API,可通过在vue.config.js中配置代理服务器。
在使用vue.js开发前端项目时,再结合webpack搞起各种依赖、各种插件进行开发,无疑给前端开发带来了很多便捷,就在解决跨域这个问题上,相信众多用vue.js的前端同僚们同我一样尝到了甜头
正向代理是你发出请求的时候先经过代理服务器,所以实际上发出请求的是代理服务器。反向代理是“代理你的目标服务器”,请求目标服务器的代理,做一些处理后再真正请求。在这篇文章里,反向代理用于处理跨域问题。
第一步,下载依赖 http-proxy-middleware;第二步,在src下建立setupProxy.js;第三步,在数据请求中直接请求,在真实url后添加/api即可,eg
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!