为啥 IE 10 拒绝通过 jQuery $.ajax 发送 POST 数据

Posted

技术标签:

【中文标题】为啥 IE 10 拒绝通过 jQuery $.ajax 发送 POST 数据【英文标题】:Why is IE 10 Refusing to send POST data via jQuery $.ajax为什么 IE 10 拒绝通过 jQuery $.ajax 发送 POST 数据 【发布时间】:2012-10-22 17:09:18 【问题描述】:

在我的开发和生产环境中,IE 10 拒绝通过简单的 $.ajax 调用发送任何 POST 数据。

我的脚本如下所示:

d = 'testvar=something';
$.ajax(
    data: d,
    success: function(h)
        console.log(h);
    
);

实际的ajax请求正在通过,但是没有post数据???

请求头看起来正常:

Request POST /steps/~do HTTP/1.1
Accept  */*
Content-Type    application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With    XMLHttpRequest
Referer http://localhost:8080/steps/
Accept-Language en-GB,en-AU;q=0.7,en;q=0.3
Accept-Encoding gzip, deflate
User-Agent  Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host    localhost:8080
Content-Length  0
DNT 1
Connection  Keep-Alive
Cache-Control   no-cache

但是请求正文是空的! (我在他们的 F12 开发栏中使用 IE 的网络选项卡来捕获请求)。在 php 脚本中,print_r($_POST); 返回一个空数组。

这在 IE 7 - 9、chrome、FF 和 safari 中运行良好,但在 IE10 中中断?

我不确定我是否遗漏了什么,或者 IE 10 是否只是错误?

编辑

我已将全局 ajax 设置如下:

$.ajaxSetup(
    url: ROOT+'~do', // ROOT is either http://localhost/.../~do or http(s)://www.steps.org.au/~do depending on production or development environment
    type: 'POST'
);

进一步编辑

在 Windows 8 Pro 64 位上使用 IE 版本 10.0.9200.16384

请求标头的直接复制/粘贴是:

Key Value
Accept  */*
Accept-Encoding gzip, deflate
Accept-Language en-GB,en-AU;q=0.7,en;q=0.3
Cache-Control   no-cache
Connection  Keep-Alive
Content-Length  0
Content-Type    application/x-www-form-urlencoded; charset=UTF-8
Cookie  __utma=91949528.1947702769.1348201656.1353212510.1353237955.6; __utmz=91949528.1348201656.1.1.utmcsr=localhost|utmccn=(referral)|utmcmd=referral|utmcct=/coconutoil.org.au/; __utmb=91949528.2.10.1353237955; __utmc=91949528; cartID=8b3b2b9187cfb1aeabd071d6ec86bbbb; PHPSESSID=bl57l7fp0h37au7g0em7i3uv13
DNT 1
Host    www.steps.org.au
Referer https://www.steps.org.au/
Request POST /~do HTTP/1.1
User-Agent  Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
X-Requested-With    XMLHttpRequest

请求正文是空的。

响应标题:

Key Value
Response    HTTP/1.1 200 OK
Server  nginx/0.7.65
Date    Sun, 18 Nov 2012 11:23:35 GMT
Content-Type    text/html
Transfer-Encoding   chunked
Connection  close
X-Powered-By    PHP/5.3.5-1ubuntu7.2ppa1~lucid
Expires Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control   no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma  no-cache

发起者

Property    Value
Stage   Document Processing
Element XMLHttpRequest
Action  Processing
Document ID 0
Frame ID    0
Frame URL   https://www.steps.org.au/Shop/Health-Products/

复制问题的页面(实际上是整个网站):

Steps to Life Shop, Health Products

【问题讨论】:

你试过使用对象吗?数据:"testvar":"something" 我在维护一个相当大的网站时遇到了同样的问题。试图找到信息/解决方法.. 我在你的网站上遇到了同样的错误,@Emmanuel——我的用户代理没有被触摸。这是 IE10 的桌面版本,而不是 Metro 版本。也许这会有所作为?编辑:确认。 Metro 版本不会出现此错误,但桌面版本会出现此错误。 Jquery Ajax call works in all browser except ie 10的可能重复 @EricLaw 在 Twitter 上帮助了我,事实上,卸载 FDM 为我解决了这个问题。再见,FDM! 【参考方案1】:

我也有同样的问题。我认为它是 ie 10 桌面版的一个错误。在 Windows 8 专业版 64 位上运行。 似乎 xhr.send 方法没有传递数据。它在所有其他浏览器中都可以正常工作,例如在 Metro 模式下 10 或者如果您在桌面模式下更改为 ie9 标准。

【讨论】:

关于它的 jQuery 错误 bugs.jquery.com/ticket/12790 基本上只是确认您观察到的行为,您可能需要添加一些评论/订阅错误。 @Nelson 是的,但他们现在已经关闭了票证,错误似乎不一致。 我在 IE 10 桌面版上遇到了同样的问题....所有其他浏览器似乎都可以正常工作。确实非常奇怪的错误......【参考方案2】:

抱歉,我尝试重现您的问题的所有尝试都没有成功。换句话说,所有 POST 都是 带有 HTTP 正文的,并且 Ajax 请求正常工作。所以我无法重现您描述的问题。我在 Internet Explorer 10、Windows 8 W64 RTM Enterprise 上进行了所有测试以及所有当前的 Windows 更新。

如果我在您引用的the page 上的聊天中添加一些项目(例如第一个项目),我可以看到 POST 请求将生成以下标头:

Anforderung       POST /~do HTTP/1.1
Accept            */*
Content-Type      application/x-www-form-urlencoded; charset=UTF-8
X-Requested-With  XMLHttpRequest
Referer           https://www.steps.org.au/
Accept-Language   de-DE,de;q=0.8,ru;q=0.7,en-US;q=0.5,en;q=0.3,ja;q=0.2
Accept-Encoding   gzip, deflate
User-Agent        Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0; Touch)
Host              www.steps.org.au
Content-Length    81
DNT               1
Connection        Keep-Alive
Cache-Control     no-cache
Cookie            __utmc=91949528; __utma=91949528.365135675.1353268932.1353268932.1353268932.1; __utmb=91949528.1.10.1353268932; __utmz=91949528.1353268932.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); PHPSESSID=ka4shsgkfvnvfdcath2klh9un0; cartID=4a90a72a379989f597276ca30c79c6f6

可以看到Content-Length是81,不是0,body是

i=1211&q=1&token=00f5e9f5768d09ae67f2016ebcb62e99a0d75345&cmd=addToCart&sideBar=1

请求将以 HTML 片段响应,按钮变为绿色。

确切地说,在将项目添加到聊天期间,它将执行您在问题中发布的另一个代码。它将执行来自shop.1352417874.js 的以下代码(第 49-74 行):

var n;
function inCart(i,t)
    var a = $('#add'+i);
    var q = t?1:$('#qty'+i).val();
    setLoader(a,(t?60:0),0);
    if(!t) a.addClass('loading').html('').attr('href','javascript:;');
    // d = 'i='+i+'&q='+q+'&token='+TOKEN+'&cmd=addToCart&sideBar=1';   
    $.ajax(
        data: 
            i:i,
            q:q,
            token:TOKEN,
            cmd:"addToCart",
            sideBar: 1
        ,
        success: function(h)
            $('#sideCartContents').replaceWith(h);
            mkButtons();
            jsEnhance();
            setLoader();
            n=0;
            if(!t) a.removeClass('loading').addClass('green').attr('href','Shop/Checkout.html').html('Checkout').parent().find('div.QTY').html('<strong>x'+q+'</strong> <span class="inC">in cart</span>');
            flashCart();
        
    );

在我的测试中本地变量iq的值为12111

所以我看不到您描述的任何错误。所以你必须在你的环境中调试代码将被复制。在测试期间,我建议您使用非最小化的 jQuery 代码。您可以调试 jQuery.ajax 的代码来定位您的问题。

不过我还有一些额外的建议给你:

    首先,您应该在$.ajax 调用中包含error 回调,而不仅仅是success 回调。 您应该查看您使用的 JavaScript 代码。例如,在上面的代码片段中,您定义了 global 变量 n,它将是全局 window 对象的属性。由于副作用以及与页面中包含的其他 JavaScript 代码冲突,引入此类变量非常危险。在其他一些地方,您可以间接设置 global window 对象的新属性。例如common.1345011838.js中定义的globaldoErrors函数的代码如下
function doErrors(e,d)
    e=e.split(',');
    for(i in e)
        $((d?d+' ':'')+'[name="'+e[i]+'"]:visible').addClass('error');
    
    errors();

在上面的代码中,您使用 i 变量而不定义它。所以你设置(或使用)window.i 变量的方式。很明显在数组不好的情况下使用for-in循环。可以用 for(var i=0,l=e.length; i&lt;l; i++) ... 等等效代码重写代码。

此外,您将common.1345011838.js的代码以

开头
var w,r,i,p,t,l,c,z,e,m,b,k,u,s,CPH,TOKEN;
var z = new Array();
var ROOT;

它定义了许多具有短名称的全局变量。这是非常糟糕的风格。它可能会与您包含的其他模块发生冲突。通常,在某个函数中定义您需要的 最多 个变量就足够了。您可以在$(document).ready(function()/*.HERE.*/); 中移动大多数变量的声明。

如果你真的需要定义一些 global 变量,你可以定义 one 就像命名空间和所有其他变量你可以定义为 properties 的唯一全局对象。这是标准做法。这样可以减少您使用的不同模块之间可能发生的冲突的数量。例如,您可以使用类似

MYGLOBALCHATOBJECT = 
    root: "/",
    z: [],
;

...
// add new property
MYGLOBALCHATOBJECT.TOKEN = "some value";

您应该在另一个函数的上下文中定义许多函数。这样您就可以减少定义许多全局变量的需要。只是一个例子上面inCart的代码使用了inCart函数上面定义的n变量。变量n仅在其他全局函数flashCart 直接在inCart 之后使用。此外,函数flashCart 将仅在回调success 内部使用。因此,您可以重写代码,以便在回调 success 中同时定义 nflashCart

...
success: function (h) 
    // define LOCAL variable n
    var n = 0;
    // define LOCAL function which can use outer variable n
    function flashCart()
        if(n<3)  
            setTimeout("flashCart()",120);
            n=n+1;
        
        $('#sideCartBox').toggleClass('highlighted');
    

    $('#sideCartContents').replaceWith(h);
    mkButtons();
    jsEnhance();
    setLoader();
    if(!t) a.removeClass('loading').addClass('green').attr('href','Shop/Checkout.html').html('Checkout').parent().find('div.QTY').html('<strong>x'+q+'</strong> <span class="inC">in cart</span>');
    flashCart(); // we use LOCAL function

我建议您另外在JSHint 或JSLint 中测试您的代码。

【讨论】:

感谢您的详细解答。我会研究你提到的事情,Javascript 不是我的强项,我主要是自学的。看来我已经学会了一些坏习惯。再次感谢。 @Emmanuel:不客气! Tree 一年前我根本不懂 JavaScript。所以我能很好地理解你。最重要的找到原因:为什么在你的测试计算机上 POST 的正文是空的。 试试 IE10 的桌面版本——它在那里失败了。 @Oleg - Windows 8 上的 IE10 可以在两种模式下运行——“桌面”(它看起来像传统的 Windows 应用程序,具有可调整大小的边框等)和“触摸/地铁”模式,其中是全屏。 Metro 模式似乎运行良好,但桌面模式却不行。 @am05mhz:我相信你。问题只是我无法在 我的带有 ie10 RTM (KB2718695) 的 win7 笔记本电脑上重现该问题。如果我在 32 位或 64 位 IE 中使用开发人员工具的网络选项卡(按 F12),我可以看到 非空 正文将在 the page 上发送。请在您的计算机上尝试该页面。需要本地化允许重现您描述的问题的确切先决条件。我在回答中只写了 IE10 并不是问题的根源。【参考方案3】:

已编辑

除了使用

之外,微软仍然没有解决此问题

&lt;meta http-equiv="x-ua-compatible" content="IE=9" &gt;

通过添加上述元标记,IE10 将在 IE9 中运行您的 javascript 兼容模式。

旧答案。

我正在发布我所做的测试的示例代码,您也可以将相同的代码用于您的代码。

<html>
<head runat="server">
    <script src="../Scripts/jquery-1.8.3.js"></script>
<script type="text/javascript">
    var xmlHttp = null;
    var XMLHTTPREQUEST_MS_PROGIDS = new Array(
      "Msxml2.XMLHTTP.7.0",
      "Msxml2.XMLHTTP.6.0",
      "Msxml2.XMLHTTP.5.0",
      "Msxml2.XMLHTTP.4.0",
      "MSXML2.XMLHTTP.3.0",
      "MSXML2.XMLHTTP",
      "Microsoft.XMLHTTP"
    );

    function makePOSTRequest(url, parameters) 

        if (window.XMLHttpRequest != null) 
            //xmlHttp = new window.XMLHttpRequest();
            xmlHttp = new ActiveXObject('Microsoft.XMLHTTP');
         else if (window.ActiveXObject != null) 
            // Must be IE, find the right ActiveXObject.
            var success = false;
            for (var i = 0; i < XMLHTTPREQUEST_MS_PROGIDS.length && !success; i++) 
                alert(XMLHTTPREQUEST_MS_PROGIDS[i])
                try 
                    xmlHttp = new ActiveXObject(XMLHTTPREQUEST_MS_PROGIDS[i]);
                    success = true;
                 catch (ex)  
            
         else 
            alert("Your browser does not support AJAX.");
            return xmlHttp;
        
        xmlHttp.onreadystatechange = alertContents;
        xmlHttp.open('POST', url, true);
        xmlHttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded; charset=UTF-8');
        //xmlHttp.setRequestHeader('Content-type', 'application/json;');
        xmlHttp.setRequestHeader('Content-Length', parameters.length);
        xmlHttp.setRequestHeader('Accept', 'text/html,application/xhtml+xml')
        //xmlHttp.setRequestHeader('Connection', "close");
        xmlHttp.send(parameters);
    

    function alertContents() 
        // alert( this.status );
        if (xmlHttp.readyState == 4) 
            //alert( this.responseText );
            if (xmlHttp.status == 200) 
                var result = xmlHttp.responseText;
                //  document.getElementById('result').innerHTML = result;
                //  document.getElementById('submitbutton').disabled = false;
                alert(result);
             else 
                //alert( this.getAllResponseHeaders() );
                alert("There was a problem with the request.");
            
        
    
</script>
</head>
<body>
<a href="javascript:makePOSTRequest('/api/jobs/GetSearchResult','jtStartIndex=0&jtPageSize=10&jtSorting=jobDescription ASC&jobDescription=')">Click me please</a>
    GetJobDetail

    <br/><br/>
    Url: <input type="text" id="url" value="/api/jobs/GetSearchResult"/><br/>
    parameters: <input type="text" id="parameters" value="jtStartIndex=0&jtPageSize=10&jtSorting=jobDescription ASC&jobDescription="/><br/>
    submit : <input type="button" id="callMethod" value = "call" onclick="javascript: makePOSTRequest($('#url').val(), $('#parameters').val())"/>
</body>
</html>

【讨论】:

【参考方案4】:

我有类似的东西 (Problems with image upload from browsers to Amazon S3),我发现在我的情况下,xhr 对象在从https://my.local.server.com:123/foo 请求http://some.server.com 时崩溃。它在 xhr.open("POST", httpUrl, true) 调用时崩溃。

这可能是一个 IE10 错误(真是令人惊讶;)),它在 Win7 和 Win8 上都崩溃了。

【讨论】:

【参考方案5】:

我也遇到了同样的问题,以下更改对我有用。

<meta http-equiv="x-ua-compatible" content="IE=9" >

为我工作:)

【讨论】:

【参考方案6】:

我遇到了同样的问题,但只有一个请求,我的意思是我有一个可以处理许多 ajax 请求的 Web 应用程序。查看您的标记。我在表格内有表格用于布局

<table>
    <form></form>
</table>

我只是换一种方式。表格 > 表格。

【讨论】:

【参考方案7】:

面对同样的问题,我无法通过设置 &lt;meta http-equiv="x-ua-compatible" content="IE=9"&gt; 来解决,但是我通过将响应头 X-UA-Compatible 设置为 IE9 来强制解决这个问题,这是推荐的方式,因为在 HTML5 验证器中无法识别元头.

对于 J2EE 应用程序,这可以通过以下过滤器来实现:

public class IECompatibilityFilter implements Filter 
    private String compatibilityMode = "IE=10";
    public IECompatibilityFilter() 
    
    public String getCompatibilityMode() 
        return compatibilityMode;
    
    public void setCompatibilityMode(String compatibilityMode) 
        this.compatibilityMode = compatibilityMode;
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException 
        String mode = filterConfig.getInitParameter("compatibilityMode");
        if (StringUtils.isNotBlank(mode)) 
            this.compatibilityMode = StringUtils.trim(mode);
        
    
    @Override
    public void doFilter(ServletRequest request,
                         ServletResponse response,
                         FilterChain chain)
            throws IOException, ServletException 
        if (!response.isCommitted() && response instanceof HttpServletResponse) 
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            httpResponse.addHeader("X-UA-Compatible", compatibilityMode);
        
        chain.doFilter(request, response);
    
    @Override
    public void destroy() 
    

并在您的web.xml 中注册。

<filter>
  <filter-name>ieCompatibilityFilter</filter-name>
  <filter-class>com.foobar.web.filter.IECompatibilityFilter</filter-class>
  <init-param>
    <param-name>compatibilityMode</param-name>
    <param-value>IE=9</param-value>
  </init-param>
</filter>

【讨论】:

【参考方案8】:

似乎存在 Window 8 问题,发出 跨域 https 请求。我无法确认它是否与证书的有效性有关,因为我的跨域服务器上的证书无效(开发服务器)。

此链接是一种解决方法,但谁愿意引导整个应用程序为 IE10+ 发出 GET 请求? http://jonnyreeves.co.uk/2013/making-xhr-request-to-https-domains-with-winjs/

【讨论】:

以上是关于为啥 IE 10 拒绝通过 jQuery $.ajax 发送 POST 数据的主要内容,如果未能解决你的问题,请参考以下文章

防止 IE 中出现“SCRIPT5:访问被拒绝”错误

IE 使 Jquery.html 失败,权限被拒绝

使用 Jquery 在 IE 8 和 7 中“权限被拒绝”

jquery 代码显示权限被 IE Edge 和 iframe 拒绝

为啥我的 jquery 表单验证不适用于 IE7?它适用于 FF、Opera、Safari 等

解决jquery ajax在跨域访问post请求的时候,ie9以下无效(包括ie9)的问题