一。引子
如果本地打开HTML文件,用的地址是本地的FILE:///d/a.html,而AJAX请求的诗服务器的地址,那么就跨域了。
跨域请求默认是不可进行的。
域:协议名(http)+主机名(www.baidu.com)+端口号(80)。 三个都相同才是相同的域。
相同域请求不受限制,不同域之间不能互相请求。
跨域请求:不同域之间的访问。
二。如何处理
1.JSON处理跨域请求
最常见的是JSPNP。 平时写在HTML页面中的<img>,<link>,<script>等标签的src属性是不受跨域请求限制的。
想法:用<script>去请求服务器的JS文件来获得需要的数据。服务器端的数据总是在更新变动,所以服务器端就有必要动态生成JS文件。
JSONP定义:服务器端动态生成J:SON文件,吧客户端需要的数据放在这个文件里面,让客户端通过<script>标签的src属性来请求这个文件。
**PS::不要混淆一个东西 。JSON以非常简单的方式来描述数据,是一种非常常用的数据传输格式;AJAX通过XMLHttpRequest对象获取非本页的内容;JSONP是为了解决客户的跨域请求,由开发者想出来的一种解决方案,而后形成的一种非正式的传输协议。
2.JSONP的使用:
通过JSONP方式写一个跨域请求,就要定义一个函数,并且用<script>标签去请求一次。可以进行封装:
ajax.jsonp = function(){
//冬天创建script标签,为了使用它的src属性去请求服务器
var script = document.createElement('script');
//随机生成函数名,不然会读取本地缓存的JS文件
var time = new Date();
var funcName = 'jaonp' + time.getTime();
//拼接URL,判断url中是否传有参数
if(url.indexOf('?')>0){ //如果url中有传递参数,这样拼接URL
url = url + '&callback=' + funcName;
}else{ //如果url中没有传递参数,这样拼接URL
url = url + '?callback=' + funcName;
//注册回调函数到全局
window[funcName] = function(data){
callback(data);
//把数据给回调函数之后销毁我们注册的函数和创建的script标签
delete window[funcName]; //删除函数
script.parentNode.removeChild(script); //删除script标签
}
//设置script标签的src属性
script.setAttribute('src',url);
//把script标签加入head,请求服务器得到数据
document.getElementByTagName('head')[0].appendChild(script);
}
2. 代理服务器处理跨域请求
把前台客户端AJAX需要跨域请求的地址交由后台服务器端,服务器通过自己的抓取工具去请求相应的地址,然后把得到的数据返回给客户端。
注意:nodegrass模块在Node.js扩展模块中是没有的,需要安装。
3.基于<iframe>标签
4.CORS
CORS是W3C推出的一种新的机制,即跨院资源共享。这种机制允许浏览器向跨源服务器发出XMLHttpRequest请求,它基于浏览器的一个内置机制,需要浏览器的支持。由于只是浏览器的支持,所以我们在使用CORS处理跨域请求的时候,浏览器判断这是一个跨域请求,会自动帮我们做好相应的跨域请求配置,添加一些附加的头信息,而我们要做的仅仅是在服务器端判断是否允许这个域访问。