文档章节

Ajax 浏览器跨域访问控制

IamOkay
 IamOkay
发布于 2014/11/20 21:35
字数 739
阅读 197
收藏 0

jsonp+ajax实现浏览器跨域通信的原理解析

php+ajax+P3P实现多域名跨域登录

一.关于跨域需要设置的响应头消息

Access-Control-Allow-Origin:*                               #允许所有主机
Access-Control-Allow-Origin:http://hello-world.example      #允许特定主机

Access-Control-Allow-Methods: POST, GET, OPTIONS            #允许跨域执行的方法

Access-Control-Allow-Headers: X-PINGOTHER,Content-Type,MyHeader                  #允许跨域设置的头信息(如果不设置,那么无法获取该值,甚至数据无法获取)

Access-Control-Max-Age: 1728000

 

二.关于IE8和IE9浏览器差异性说明 

IE8和IE9使用新的API   XDomainRequest(IE又淘气了一次,但还好IE7上可以通过ajax跨域)

var xdr = new XDomainRequest();
   xdr.onload = function (e) { //当收到服务器响应的回调函数
            var data = $.parseJSON(xdr.responseText);
            if (data == null || typeof (data) == 'undefined') {
                data = $.parseJSON(data.firstChild.textContent);
            }
            //success
   };
  xdr.onerror = function (e) {
            //error
   }

xdr.open("GET", url); //目前只支持IE8和IE9
xdr.send();

对于webkit阵营的浏览器而言,需要使用ajax,这里我们不在多演示,我们将在下面做一个兼容性的例子。

 

三.为了达到兼容性的指标,我们进行如下改造

设立一站点 www.a.com,作为请求的client

<!doctype html>
<html>
	<head>
		<meta charset="utf-8" />
		<title>Cross-Domain</title>
		<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
	</head>
	<body>
	<script type="text/javascript" charset="utf-8">
	var xdr = null;
	if(!!window.XMLHttpRequest)
	{
		xdr = new XMLHttpRequest();
	}
	else if( window.ActiveXObject)
	{
		try
		{ //IE7+
			xdr = new ActiveXObject("Msxml2.XMLHTTP");
		}
		catch (e) 
		{
			//IE6-
			try { xdr = new ActiveXObject("Microsoft.XMLHTTP");} catch (e) { } 
		}
	}

	if(xdr)
	{		
        	if(!("withCredentials" in xdr) && window.XDomainRequest) 
        	{
        		xdr = new XDomainRequest();
        	}else{
        		xdr['withCredentials'] = true;
        	}
        				
        	if(window.XMLHttpRequest && (xdr instanceof XMLHttpRequest))//如果是IE6,IE7,chrome,firefox,IE10,IE11
        	{
        		xdr.open('OPTIONS', 'http://www.b.com/html5/crossdomain-server.php', true);
        	}
        	else if(window.ActiveXObject&&(xdr instanceof XDomainRequest))//如果是IE8,IE9
        	{
        		xdr.open("POST", "http://www.b.com/html5/crossdomain-server.php");
        	}
				
	
		xdr.onload = function(e) 
		{
			xdr.onReadyStateChange(arguments);  
		};

		xdr.onReadyStateChange = function(e)
		{
			if(window.console)
			{
				console.dir(xdr.responseText);
			}else{
				alert(xdr.responseText);
			}
		}
					
		 xdr.send(null);
	}
	else
	 {
		alert('Not Supported !');
	 }	

		</script>
	</body>
</html>

 

设立服务器站点   www.b.com/html5/crossdomain-server.php

<?php
header('Content-Type:application/json;charset=utf-8');
header('Pragma:no-cache,no-store');
header('Cache-Control:no-cache,private');
header('Date:'+date('r'));
header('Connection:Keep-Alive');

header('Access-Control-Allow-Origin: http://www.a.com');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS,PUT,DELETE,HEAD');
header('Access-Control-Allow-Headers: X-PINGOTHER,Content-Type,Accept,Range');
header('Access-Control-Max-Age: 1728000');
header('Access-Control-Allow-Credentials: true');

date_default_timezone_set('Asia/Chongqing');

$data = array(
	'id'  => 'ZF1024',
	'name'=>'zhangsan',
	'token'=>uniqid()
);


echo json_encode($data);

?>

 

请求结果

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

三.html5 postMessage 进行跨域

a.com/index.html中的代码:

<iframe id="ifr" src="b.com/index.html"></iframe>
<script type="text/javascript">
window.onload = function() {
    var ifr = document.getElementById('ifr');
    var targetOrigin = 'http://b.com';  // 若写成'http://b.com/c/proxy.html'效果一样
                                        // 若写成'http://c.com'就不会执行postMessage了
    ifr.contentWindow.postMessage('I was there!', targetOrigin);  //通过这句穿透域名限制
};
</script>
b.com/index.html中的代码:

<script type="text/javascript">
    window.addEventListener('message', function(event){
        // 通过origin属性判断消息来源地址
        if (event.origin == 'http://a.com') {
            alert(event.data);    // 弹出"I was there!"
            alert(event.source);  // 对a.com、index.html中window对象的引用
                                  // 但由于同源策略,这里event.source不可以访问window对象
        }
    }, false);

 

最后,你还可以通过apache服务器设置跨域

<IfModule mod_setenvif.c>
    <IfModule mod_headers.c>
        <FilesMatch "\.(cur|gif|ico|jpe?g|png|svgz?|webp)$">
            SetEnvIf Origin ":" IS_CORS
            Header set Access-Control-Allow-Origin "*" env=IS_CORS
        </FilesMatch>
    </IfModule>
</IfModule>

 

参考:http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html#m2

         http://msdn.microsoft.com/zh-cn/library/gg589525(v=vs.85).aspx

 

 

© 著作权归作者所有

IamOkay

IamOkay

粉丝 203
博文 483
码字总数 403198
作品 0
海淀
程序员
私信 提问
JS跨域请求(script标签)和JQuery跨域请求(jsonp)

前言: 为尽可能保证浏览器端安全,浏览器会遵循SOP协议,即同源协议 ajax无法完成跨域请求 $.get $.post $.ajax都不可以 jsonp作为ajax的一种扩展协议可以完成跨域请求 $.getJson()也可以完...

big_cat
2015/11/11
268
0
ajax和jsonp没有半点关系,跨域问题

jsonp确实和ajax没有半毛钱关系,只算是一种机制跨域数据获取方案或者协议。 只是说很多库(比如jquery)里面对jsonp和ajax做了一样的封装,看起来就好像jsonp是ajax的一部分一样,这好像会造...

SubinY
2016/12/26
104
0
AJAX跨域调用相关知识-CORS和JSONP(引)

AJAX跨域调用相关知识-CORS和JSONP 1、什么是跨域 跨域问题产生的原因,是由于浏览器的安全机制,JS只能访问与所在页面同一个域(相同协议、域名、端口)的内容。 但是我们项目开发过程中,经...

辉煌霸猪
06/26
53
0
Ajax跨域问题研究笔记

作者:fbysss msn:jameslastchina@hotmail.com blog:blog.csdn.net/fbysss 声明:本文由fbysss原创,转载请注明出处 关键字:Ajax跨域 一.试验准备 修改c:/windows/system32/drivers/etc/hos...

长平狐
2012/10/17
314
0
浏览器同源策略及 Ajax 跨域解决方案

因为在开发过程中会经常遇到因为浏览器同源策略而导致的跨域问题,而多数开发者对浏览器同源策略和跨域问题并没有很清晰的认识,所以打算在这篇文章中说下浏览器同源策略和我们最经常会遇到的...

淘淘笙悦
2018/07/13
0
0

没有更多内容

加载失败,请刷新页面

加载更多

springboot集成elasticsearch-rest-high-level-client的坑

我使用的是Elasticsearch7.2.0,由于官网上推荐使用elasticsearch-rest-high-level-client端集成在springboot所以尝试爬坑。 首先直接引入官网的配置文件 <dependency> <grou...

MuzzyXu
26分钟前
5
0
ECMAScript运算符之《等性运算符》

等性运算符一般用在判断两个变量是否相等的运算。在处理原始值时,这种运算相当简单,涉及对象,任务就稍有点复杂。 性运算符分: 1、等号和非等号用于处理原始值 2、全等号和非全等号用于处...

专注的阿熊
28分钟前
4
0
ssh-keygen -t rsa -C "注释内容,一般为邮件地址",生成的公钥后面会带上注释,这个注释有什么用处呢?

ssh-keygen -t rsa -C "注释内容,一般为邮件地址",生成的公钥后面会带上注释,这个注释有什么用处呢? donhui 发布于 2015/11/12 16:47 阅读 5K+ 收藏 0 答案 1 补充话题 OpenSSH 为什么8...

linjin200
31分钟前
4
0
Proxy用法——让我们创建一个API代理器

什么是Java Proxy? MDN对Proxy 的定义是: Proxy对象用于定义基本操作的自定义行为(如属性查找、赋值、枚举、函数调用等)。 通俗的将,Proxy对象是目标对象的一个代理器,任何对目标对象的...

AiChinaTech
34分钟前
5
0
Nginx--面试基础必会

文章原创于公众号:程序猿周先森。本平台不定时更新,喜欢我的文章,欢迎关注我的微信公众号。 最近一直在更新关于Nginx的系列文章,终于将Nginx的几个关键知识点讲的差不多了。本篇作为Ngi...

程序猿周先森
36分钟前
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部