2010-06-02 72 views
8

我有一個HTML頁面需要使用jQuery AJAX函數向受CAS保護的(Central Authentication Service)Web服務發出請求。我有以下代碼:CAS認證和使用jQuery重定向AJAX

$.ajax({ 
    type: "GET", 
    url: request, 
    dataType: "json", 
    complete: function(xmlHttp) { 
     console.log(xmlHttp); 
     alert(xmlHttp.status); 
    }, 
    success: handleRedirects 
}); 

request變量可以是到CAS服務器(https://cas.mydomain.com/login?service=myServiceURL),或直接到服務(當時應該重定向到CAS獲得服務票證)。 Firebug顯示該請求正在進行,並且作爲302重定向返回。但是,$.ajax()函數不處理重定向。

我寫了這個功能,解決此問題:

var handleRedirects = function(data, textStatus) { 
    console.log(data, textStatus); 
    if (data.redirect) { 
     console.log("Calling a redirect: " + data.redirect); 
     $.get(data.redirect, handleRedirects); 
    } else { 
     //function that handles the actual data processing 
     gotResponse(data); 
    } 
}; 

然而,即使這樣,handleRedirects功能不會被調用,而xmlHttp.status總是返回0。它看起來並不像Cookie正在通過cas.mydomain.com調用發送。 (請參閱this question以解決類似的問題。)

這是AJAX調用不處理重定向的問題,還是有更多的事情在這裏發生?

回答

5

確實比看到的還要多。

經過一番調查,似乎jQuery AJAX請求以這種方式做出失敗,如果他們不是對同一個子域。在這個例子中,請求從不同的服務器到cas.mydomain.com。即使它也在mydomain.com上,請求將失敗,因爲子域不匹配

jQuery AJAX的確處理重定向。我在同一個子域中使用腳本進行了一些測試以驗證。另外,Cookie也會按照您的預期傳遞。本研究見my blog post

另請注意,協議必須相同。也就是說,因爲cas.mydomain.com正在使用HTTPS,所以您從中調用它的頁面也必須使用HTTPS,否則請求將失敗。

+1

你有沒有找到解決這個問題的解決方案?我閱讀了您的博客文章,提供JSONP,這是我在其他地方讀過的。但是,看起來像CORS是解決這個問題的方法,但我仍然無法使302重定向正常工作。 – aasukisuki 2012-12-22 03:19:49

0

瀏覽器不允許跨域調用。最簡單的方法是在移動應用程序端使用JSONP並使用CAS網關返回票證。

1

您可以使用PHP代理進行跨域AJAX調用。在以下示例中,代理能夠調用返回JSON字符串的REST Web服務。

wsproxy.php

<?php 

if (!isset($_POST["username"]) || !isset($_POST["password"])) 
    die("Username or password not set."); 

$username = $_POST["username"]; 
$password = $_POST["password"]; 

if (!isset($_GET['url']) 
    die("URL was not set."); 

//Rebuild URL (needed if the url passed as GET parameter 
//also contains GET parameters 
$url = $_GET['url']; 
foreach ($_GET as $key => $value) { 
    if ($key != 'url') { 
     $url .= "&" . $key . "=" . $value; 
    } 
} 

//Set username and password for HTTP Basic Authentication 
$context = stream_context_create(array(
    'http' => array(
    'header' => "Authorization: Basic " . base64_encode("$username:$password") 
    ) 
)); 

//Call WS 
$json = file_get_contents($url, false, $context); 

// Read HTTP Status 
if(isset($http_response_header[0])) 
    list($version,$status_code,$msg) = 
     explode(' ',$http_response_header[0], 3); 

// Check HTTP Status 
if($status_code != 200) { 
    if($status_code == 404) { 
     die("404 - Not Found"); 
    } else { 
     die($status_code . " - Error"); 
    } 
} 

//Add content header 
header('Content-Type: application/json'); 
print $json; 

?> 

URL使用

http://yourDomain.com/wsproxy.php?url=https://wsToCall.com/ws/resource?param1=false&param2=true

jQuery的$.ajax$.post

請注意,如果您不需要傳遞用戶名和密碼,那麼GET請求就足夠了。

$.ajax({ 
    type : "POST", 
    url : "http://" + document.domain + 
     "/wsproxy.php?url=http://wsToCall.com/ws/resource?param1=false&param2=true", 
    dataType : "json", 
    success : handleRedirects, 
    data: { username: "foo", password: "bar" } 
}); 
+0

您可能遇到的問題是代理不會使用用戶的會話信息。在我的情況下,我試圖通過向CAS服務器發送服務器端請求來將用戶登錄到CAS服務中 - 我獲得的服務票據在服務上對它們進行了身份驗證,但它們沒有登錄到服務器本身(丟失了一些開始使用SSO設置的好處)。 – DaveMongoose 2017-09-21 17:35:34