THE SCRIPT TAG HACK
Security restrictions prevent us from using XMLHttpRequest to access any
domain other than the one serving up the JavaScript file being executed. This
means we can’t access remote servers like this:
js文件所在域名 www.a.com
XMLHttpRequest请求域名 www.b.com
是不行的。
同源策略,它是由Netscape提出的一个著名的安全策略。现在所有支持JavaScript 的浏览器都会使用这个策略。所谓同源是指,域名,协议,端口相同。当一个浏览器的两个tab页中分别打开来 百度和谷歌的页面当一个百度浏览器执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。
<script>标签的src属性并不被同源策略所约束,所以可以获取任何服务器上脚本并执行。
Cross Domain AJAX主要就是A.com网站的页面发出一个XMLHttpRequest,这个Request的url是B.com,这样的请求是被禁止的。关于 Cross Domain AJAX的安全问题现在还在被大家讨论着。不过就目前的情况来看,一定要靠一些非常规手段来解决这个问题了。当前比较流行的解决方法主要有下面几种:
-
跨域代理(Cross Domain Proxy)。主要原理就是用php或者其他语言写一个代理请求的转发过程。客户端请求自己的服务器,服务器把请求转发到目标地址并且得到回应,服务器再 把结果返回给客户端。这个过程,对于开发者来说还是不错的选择,因为你可以在服务器上对回应的结果做自己的处理,可以决定需不需把结果要返回给客户端。
-
JSON+动态添加脚本标签(JSON+Dynamic Script Tag)。实现的主要原理是,远端服务器返回的不是XML格式的数据,而是JSON格式的数据。而客户端发出请求的过程,其实是在页面动态的增加一个诸如 <script src="”请求地址”" type="text/javascript"></script> 标签,这个过程会把请求到的那个js文件跑一边,利用这点特性,我们动态的得到了数据。 (JSON and the Dynamic Script Tag: Easy, XML-less Web Services for JavaScript)
-
使用Flash来跨域请求。 有人想出在本地增加一个Flash文件,靠Flash文件来请求跨域的资源。具体方法可以看( Cross-domain AJAX using Flash 与 Flash to the Rescue)。我尝试了一下,不过发现这种方式的请求需要远端服务器上有一个crossdomain.xml文件,这个文件用来描述可访问本资源的网站。
第一种方法只要在发起请求端有所改变就能实现跨域,而后两种都需要同时在发起请求端和回复请求端做点事情才能实现。第一种方式比较简单,对于已有的 系统改动不大。但是,第二中方式却是现在的发展趋势,不可小视。不过在我目前的状况(只能纯写HTML+JS,没有其他权限)下,看上去对跨域是无能为力 了……
第一种跨域代理详细过程:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>使用代理服务器脚本</title> <script type="text/javascript" src="proxyping.js"> </script> </head> <body> js仅仅允许向该域名下的服务器发生http请求,如何实现跨域 办法:不用js直接访问远程服务器,而使用本地服务器上的php脚本访问客户端的远程服务器即可。 <br/> <div id="data" style="color:red;"> <button onclick="var serverAddress='proxyping.php'; var serverParams='&name=jack'+'&value=hello'; process(serverAddress+'?'+serverParams); " > 点此获取数据</button> </div> </body> </html>
proxyping.js就是一般的ajax的函数调用过程:
function getHTTPObject() {
var xhr = false;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
} catch(e) {
try {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
} catch(e) {
xhr = false;
}
}
}
return xhr;
}
function process(file) {
var request = getHTTPObject();
if (request) {
request.onreadystatechange = function() {
parseResponse(request);
};
request.open("GET", file, true);
request.send(null);
}
}
function parseResponse(request) {
if (request.readyState == 4) {
if (request.status == 200 || request.status == 304) {
var data = document.getElementById("data");
data.innerHTML = request.responseText;
}
}
}
关键在于proxying.php它接受我们的ajax中open(get )方法传递的数据,并返回结果;]
<?php $name=$_GET['name']; $value=$_GET['value']; $serverAddress="http://www.google.com"; $serverParams="&name=".$name."&value=".$value; $result=file_get_contents($serverAddress.'?'.$serverParams); echo $result; ?>
用file_get_contents读取远程服务器返回的地址;这里我们随便写的是一个远程服务器google.com。当然,这里传递的参数name和value都是无意义的。随便的.
2:使用jquery
<script> $.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?", { tags: "cat", tagmode: "any", format: "json" }, function(data) { $.each(data.items, function(i,item){ $("<img/>").attr("src", item.media.m).appendTo("#images"); if ( i == 3 ) return false; }); }); </script>
或者:
<script> function jsonpCallback(result) { alert(result); } </script> <script type="text/javascript" src="http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=jsonpCallback"></script>
3.使用JSONPhttp://www.ibm.com/developerworks/cn/web/wa-aj-jsonp1/
http://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html
request.open("GET", "http://api.search.yahoo.com/", true);
We can’t use XMLHttpRequest to access the Web APIs offered by so many
sites these days. That’s a real shame because most APIs return their data in
XML, which would then be available in responseXML.
The script element has no such security restrictions. It’s possible to access
a JavaScript file from another domain in this way:
<script type="text/javascript"
src="http://www.google-analytics.com/urchin.js"></script>
If you can request a JavaScript file from another domain, then you can also
request a JSON file. Remember, JSON is nothing more than JavaScript.
Using some DOM Scripting, you can dynamically generate a script element.
This function accepts a URL as its argument. It creates a new script element
with the URL as its src attribute, and then adds the element to the head of
the document:
ADVANTAGES OF JSON
As a format for transmitting data, JSON is quite similar to XML, but it is a bit
more lightweight. Whereas every value in XML requires an opening and a
closing tag, JSON only requires a name to be written once.
Unlike XML, JSON doesn’t need to be sent from the server with a specific
content-type header. It can be sent as plain text.
JSON’s greatest asset is its ability to travel across domains. This means abandoning
the XMLHttpRequest object in favor of the script tag hack, but right
now, that’s the only way of directly retrieving data from another server.