AJAX应用之setRequestHeader位置
Ajax这玩意越用出现的情况越多,除了本身的一些限制,还有一些就是与众多浏览器的实现策略有关了。平时为了调试方便都是在ff下使用,现在就有这么一个问题,在ajax.open用post方式时,我们都清楚需要设置Hearder的几个参数,于是这样写:
xmlReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlReq.setRequestHeader("Content-length", paramsSend.length);
xmlReq.setRequestHeader("Connection", "close");
xmlReq.open("POST", url );
xmlReq.onreadystatechange = successResponse;
xmlReq.send(paramsSend);
这里在IE上运行不会出现任何问题,但一在FF上运行就会出现错误:
经查询,该问题与ff中对于Ajax的实现有关,在ff中对于AJAX的nsXMLHttpRequest.cpp文件中有:
/* void setRequestHeader (in AUTF8String header, in AUTF8String value); */
1644 NS_IMETHODIMP
1645 nsXMLHttpRequest::SetRequestHeader(const nsACString& header,
1646 const nsACString& value)
1647 {
1648 if (!mChannel) // open() initializes mChannel, and open()
1649 return NS_ERROR_FAILURE; // must be called before first setRequestHeader()
1650
1651 // Prevent modification to certain HTTP headers (see bug 302263), unless
1652 // the executing script has UniversalBrowserWrite permission.
1653
1654 nsCOMPtr<nsIScriptSecurityManager> secMan =
1655 do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
1656 if (!secMan)
1657 return NS_ERROR_FAILURE;
1658
1659 PRBool privileged;
1660 nsresult rv = secMan->IsCapabilityEnabled("UniversalBrowserWrite",
1661 &privileged);
1662 if (NS_FAILED(rv))
1663 return NS_ERROR_FAILURE;
1664
1665 if (!privileged) {
1666 const char *kInvalidHeaders[] = {
1667 "host", "content-length", "transfer-encoding", "via", "upgrade"
1668 };
1669 for (size_t i = 0; i < NS_ARRAY_LENGTH(kInvalidHeaders); ++i) {
1670 if (header.LowerCaseEqualsASCII(kInvalidHeaders[i])) {
1671 NS_WARNING("refusing to set request header");
1672 return NS_OK;
1673 }
1674 }
1675 }
1676
1677 nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(mChannel));
1678
1679 if (httpChannel) {
1680 // We need to set, not add to, the header.
1681 return httpChannel->SetRequestHeader(header, value, PR_FALSE);
1682 }
1683
1684 return NS_OK;
1685 }
从执行的第一行就可以看清楚,mChanel变量需要先在open方法里面初始化。原来如此,在FF里面需要将open方法放在setRequestHeader之前。OK。
xmlReq.open("POST", url );
xmlReq.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlReq.setRequestHeader("Content-length", paramsSend.length);
xmlReq.setRequestHeader("Connection", "close");
xmlReq.onreadystatechange = successResponse;
xmlReq.send(paramsSend);
搞定,收工。