实现
让我们看一下服务器端代码,例子如下(ASP.NET和PHP)
ASP.NET (C#)
protected void Page_Load(object sender, EventArgs e)
{
String data = String.Empty;
String returnJSONStr = String.Empty;
switch (Request.HttpMethod)
{
case "GET":
data = Request.QueryString["Data"];
returnJSONStr = "{\"Data\":\"Hi remote friend, you tried to passed me data: *" + data + "* through HTTP GET.\"}";
break;
case "POST":
data = Request.Form["Data"];
returnJSONStr = "{\"Data\":\"Hi remote friend, you tried to POST some mock data: *" + data + "* to me.\"}";
break;
case "OPTIONS":
break;
default:
returnBadRequestResponse();
break;
}
if (String.IsNullOrEmpty(data))
returnBadRequestResponse();
else
{
Response.AddHeader("Access-Control-Allow-Origin", "*");
Response.ContentType = "application/json";
Response.Write(returnJSONStr);
}
}
private void returnBadRequestResponse()
{
Response.StatusCode = 400;
Response.ContentType = "application/json";
Response.Write("{\"Error\":\"Bad HTTP request type!\"}");
}
PHP
if(isset($["Data"]))
{
$method=$_SERVER['REQUEST_METHOD'];
$data="";
if($method=="POST")
{
$data=$_POST["Data"];
$fakeData=new FakeData();
$fakeData->Data="Hi remote friend, you tried to POST some mock data: *"+data+"* to me.";
$fakeData->Time=new DateTime("now");
}
elseif($method=="GET")
{
$fakeData=new FakeData();
$fakeData->Data="Hi remote friend, you tried to passed me data: *"+data+"* through HTTP GET.";
$fakeData->Time=new DateTime("now");
}
else
{
RaiseError();
}
header('Content-type: application/json');
$jsonStr= json_encode($fakeData);
echo($jsonStr);
}
else
{
RaiseError();
}
function RaiseError()
{
http_send_status(405);
header("Status: 405 Method Not Allowed");
}
/*Classes definition*/
class FakeData
{
public $Data;
public $Time;
}
客户端AJAXY发起请求代码:
var cor = null; // cor stands for Cross-Origin request
if (window.XMLHttpRequest) {
cor = new XMLHttpRequest();
}
//else if (window.XDomainRequest) {
//cor = new XDomainRequest();
//}
else {
alert("Your browser does not support Cross-Origin request!");
return;
}
cor.onreadystatechange = function () {
if (cor.readyState == 4) {
document.getElementById('lbl').innerHTML = cor.responseText;
}
};
var data = 'Some fake data';
if (method == 'POST') {
cor.open('POST', 'http://WayneYe.com/Demo/CORSDemo/CORSDemoServer.aspx', true);
cor.withCredential = "true";
cor.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
cor.send('Data=' + data);
}
else if (method == 'GET') {
cor.open('GET', 'http://WayneYe.com/Demo/CORSDemo/CORSDemoServer.aspx?Data=' + data, true);
cor.withCredential = "true";
cor.send(null);
}
JS代码适用于所有主流浏览器(IE8+, FF 3.6+, Chrome 8+),我没有用IE8所采用的XDomainObject,因为 IE8+, FF and Chrome, Safari等浏览器支持XMLHTTP请求。而且XDomainObject(XDR)似乎有很多限制(参考: http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx)
结论
跨源资源共享为网站开发人员实现跨源通信提供了一个安全,灵活,标准的方案。也许是时候摈弃像JSONP,Flash,Silverlight,server bridge以及window.name等等并不是很实用的方法。
参考资料