{{js跨域请求解决方案续}}Cross-domain XMLHttpRequest(使用Apache mod_rewrite实现跨域请求)

The other day I was trying some cross-domain XMLHttpRequest stuff. As you probably know, XMLHttpRequest doesn’t work well across domains. (I was testing it locally; with all the coolness, domain restrictions didn’t hit me once.) The solutions is simple—mod_rewrite. I’m not sure if there are docs that talk about this, so I thought it’d be useful to put together this mini how-to. (If you know about the cross-domain issues, you might want to dive to the last section.)

Cross-domain?

Before we get into any of that, following is an example set of functions that would typically form your XMLHttpRequest workhorse »

function getXmlHttpObject(){
	if (window.XMLHttpRequest)
		return new XMLHttpRequest();
	else if (window.ActiveXObject)
		return new ActiveXObject("Microsoft.XMLHTTP");
	else {
		alert("XMLHttpRequest not supported!");
		return null;
	}
}

function handleHttpResponse() {
	if (http.readyState == 4) {
		results = http.responseText;
		alert(results);
	}
}

function doSomeStuff() {
	var post_arg1 = document.my_form.post_arg1.value;
	var post_arg2 = document.my_form.post_arg2.value;
	var post_url = 'http://yahoo.com/form_do'
	post_data = 'post_arg1=' + post_arg1 + '&post_arg2=' + post_arg2;
	http.open("POST", post_url);
	http.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
	http.send(post_data);
	http.onreadystatechange = handleHttpResponse;
	return false;
}

var http = getXmlHttpObject();

I’m not going to get into the not-so-gory details of XMLHttpRequest (Ajax, or whatever), there’s tons of places you’ll find good information. (I particularly recommend the last link if you’re new to all this stuff.)

So, getting back on track, the whole point of putting up those lines of code was to illustrate what “cross-domain” means. The last of the three functions that you see is the one that would be called to perform the action. Assume that the above script is within an HTML file, whose URL is, say:

http://premshree.org/form

So, some action (onBluronClickonSubmit, etc.) in form (resides on premshree.org) triggers doSomeStuff(), which in turn makes an XMLHttpRequest request to form_do, which resides on another domain (</tt>yahoo.com</tt>).

Notice the mismatch between the domains of the location of our HTML file (form) and the file that does the action (form_do)? That domain mismatch is precisely what cross-domain is.

XMLHttpRequest is insanely awesome. However, it has domain restrictions. That is, both files—the file where the call is being made, and the file to which the call is being made—need to be within the same domain.

Hold on, cross-domain XMLHttpRequest works... kinda

Actually, cross-domain requests are handled in their own different ways by MSIE and Mozilla. You can do cross-domain requests in MSIE; however, this involves changing its default security settings, or by adding certain hosts to your “trusted hosts” list. Quoting from here:

...
This is how cross-domain security fundamentally works. It's far from a perfect system, but it's simple. Since there is no way to specify which pages trust other pages to access their data, Internet Explorer simply says that if two pages are not in the same domain, they cannot communicate. More precisely, Zone Manager (found on the security tab in Internet Settings) does allow the user to say that a page may access another page, but as you point out, most people leave it set on prompt. You can suggest users add the page to the trusted site zone, or merely say Yes to the dialog box.
...

Mozilla, on the other hand, has the concept of signed scripts. You need to enable one or more of the UniversalBrowser* privileges, depending on the different domains involved in the cross-domain request. For example, if you’re accessing a remote host from your local file system—that is, accessing http:// files from file://—you need to enableUniversalBrowserRead privilege.

Nah, screw it

The reality of the situation is that cross-domain XMLHttpRequest doesn’t work as well as we would want it to on the browsers that we deeply care about, unless, of course, you are insane enough to be willing unsuspecting, naïve users to deal with things like signed scripts and trusted hosts.

Is there a solution?

Yes, thanks to some mod_rewrite magic. All we need is the RewriteRule directive.

The configuration changes need to be made to the configuration file (typically httpd.conf) of the Apache server that serves the file that makes the request (form, in our example; that is, the server that premshree.org runs on). Here are the steps involved:

  • First, Apache must be configured with proxy enabled »

    ./configure --enable-proxy

  • Make sure RewriteEngine is enabled »

    RewriteEngine on

  • Add the following rule »

    RewriteRule ^/form_do$ http://yahoo.com/form_do [P]

    The P flag that you see there indicates a pass-through proxy.

    So now instead of requesting http://yahoo.com/form_do (see bold line in the code; I knew those lines of code would be kinda useful), request for /form_do. So our request code will look like this »

    var post_url = '/form_do';

    That’s it, you’re done.

So there, a solution that cares a damn about the browser you’re using.

Caveat

Note that when you do something like this—dealing with proxies—you need to be very careful about security issues. I’m not terribly good at this, so I’m afraid I might not be able to answer your questions concerning those issues.

Many thanks to Gopal for lot of the information.

Edit [2005-11-21 10:13]: Jason Lewitt has an article on ways to get get around cross-domain XMLHttpRequest. One of them is the pass-through proxy that I discussed here.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值