Jquery Ajax请求被调用两次,第一个请求不在标头中发送令牌

时间:2012-11-28 21:31:51

标签: javascript jquery ajax

我使用ajax来调用基于WCF REST的服务。

在加载页面之前调用ajax方法。 我希望在ajax请求的标头中发送一个“令牌”。在小提琴手中,这就是我所看到的:

1.)在标头中没有令牌的服务请求。(AJAX呼叫失败) 2.)使用标头中的令牌向同一服务发出请求。(AJAX Call Passed)

之后一切正常,铬和野生动物园。但IE 10和Mozilla上只有一个服务调用。因此,服务调用在IE 10和Mozilla中失败,因为请求的标头中没有令牌。

这是我打电话的方法:

function callservice (method, serviceUrl, params, successHandler, errorHandler) {
    $.ajax({
        crossDomain: true,
        type: method,
        url: serviceUrl,
        beforeSend: function (XMLHttpRequest) { XMLHttpRequest.setRequestHeader("Authorization", Token); },
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: successHandler,
        error: errorHandler
    });
    function photos(data) {
        alert(data);
        console.log(data);
    };
}

我控制Web服务和应用程序(调用此Web服务)。当应用程序和Web服务都托管在本地主机上时,不会出现此问题。在这种情况下,只有一个成功的服务调用。但是当有跨域调用时,有两个AJAX调用。

我的问题是为什么AJAX请求在第一次尝试时没有发送令牌? 为什么令牌只在第二次AJAX调用中发送?

非常感谢任何形式的帮助。

3 个答案:

答案 0 :(得分:7)

问题在于CORS.Earlier,浏览器不允许将ajax请求发送到与客户端不同的域,因为它被视为安全威胁。现代浏览器可以使跨域ajax请求持续时间长当服务器与客户端合作时。这就是当浏览器发出跨域请求时实际发生的情况:

1.)首先,浏览器向服务发送'预检'请求,以便从WCF服务收集授权信息(这是一个请求,标题方法为我的情况下的'OPTIONS')。作为回报,Web服务将Access Control Allow Origin作为其响应头的一部分发送。由于此请求而在fiddler上显示的错误是HTTP 500错误。这个AJAX请求在数据字段中没有任何内容,因为它只是一种查找WCF服务的授权详细信息的方法。

2.)Chrome和Safari随后向Web服务发出了第二个请求,因为他们拥有该服务的授权详细信息。因为有一个HTTP,因此Firefox和IE不喜欢向该服务发出第二个ajax请求飞行前请求500错误。因此,Chrome和Safari都可以与该服务进行通信。

所以解决方案是修改来自WCF服务的响应,以防有“预检请求”。我修改了服务发送的响应,以防有“预检请求”发送HTTP 200好的回应。这允许IE和Mozilla等浏览器在预检请求之后发送实际请求。

以下是我提到的其中一个来源: http://www.bennadel.com/blog/2327-Cross-Origin-Resource-Sharing-CORS-AJAX-Requests-Between-jQuery-And-Node-js.htm

希望这可以帮助人们面对同样的问题。

答案 1 :(得分:0)

跨域调用属于同一原始策略。默认情况下,您无法拨打电话。您需要使用CORS或JSONP或代理。

答案 2 :(得分:-1)

XMLHttpRequest:除非他们改变它,否则使用MS Explorer你需要使用ActiveXObject(“Microsoft.XMLHTTP”)。对于我在普通JS中进行的ajax调用,我使用这一行来根据浏览器创建对象:

if (window.XMLHttpRequest){
   //for most BRowsers
   r = new XMLHttpRequest(); 
} else{ 
   //for Explorer
   r = new ActiveXObject("Microsoft.XMLHTTP");
}

然后在我的情况下将你的beforesend应用到这里创建的对象(r​​)。我真的相信这是你与EI的问题。但没有经过测试。