Archive for 七月, 2013

通杀各个浏览器的跨域post

星期二, 七月 9th, 2013

jquery提供的ajax挺好的,然而它的post在ie浏览器里,服务器是收不到包的。即使是chrome,服务器也得在回复的时候,重置header。

下面是代码:

1. chrome等高级浏览器

$.ajax({
type: ‘POST’,
url: “http://api2.shallwe.net/post”,
dataType: “json”,
crossDomain: true,
data: {
xxx:”111″
},
success: callback
});

然后在服务器端

self.set_header(“Access-Control-Allow-Origin”, self.request.headers.get(‘Origin’, ”))
self.set_header(“Access-Control-Allow-Credentials”, “true”)
self.set_header(“Access-Control-Allow-Methods”,
“GET,PUT,POST,DELETE,OPTIONS”)
self.set_header(
“Access-Control-Allow-Headers”,
“Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, X-Requested-By, If-Modified-Since, X-File-Name, Cache-Control”
)

 

2. ie6 ie7

这两个浏览器里,没有高级的接口用,只能用最原始的,iframe 和 form

var callback = function () {
alert(‘callback’);
};

var ifr = document.createElement(“iframe”),
form = document.createElement(“form”),
id_input = document.createElement(“input”);
try {
ifr = document.createElement(‘<iframe name=”for_post”>’);
} catch (ex) {
ifr = document.createElement(‘iframe’);
ifr.name = “for_post”;
}
ifr.id = “for_post”;
$(ifr).css(“display”, “none”);
document.body.appendChild(ifr);

form.action = “http://api2.shallwe.net/post”;
form.method = “post”;
form.target = “for_post”;
$(form).css(“display”, “none”);
document.body.appendChild(form);

id_input.type = “hidden”;
id_input.name = “order_id”;
id_input.value = order.id();
form.appendChild(id_input);
form.submit();

if (ifr.attachEvent) {
ifr.attachEvent(“onload”, callback);
} else {
ifr.onload = callback;
}

 

3. ie8 下

在解决方案2中,form提交给iframe,如果在ie8和9中,会出现安全提示,这个显然不能接受。还好ie8之后有个牛叉的XDomainRequest

var data = {
id: “xxx”,

};
var xdr = new XDomainRequest();

xdr.onload = function (resp) {
callback();
};
xdr.open(‘POST’, ‘http://api2.shallwe.net/post’)
xdr.send($.param(data));

但是这个里面有个暗门,因为在ie8下,你发出去的xdomainrequest是没有content-type的,这样很多服务器程序,例如tornado (据说php也是)是不会解析你的request.body的,即你得不到post的内容,这时候就需要你手动解析一遍

我用的tornado,我是这样做的

def post(self):

if not self.request.headers.get(“Content-Type”, None):

self.request.headers[‘Content-Type’] = “application/x-www-form-urlencoded”

httputil.parse_body_arguments(

self.request.headers.get(“Content-Type”, “”), self.request.body,

self.request.arguments, self.request.files)

如果是php,估计就是另外的处理方法了