2009-10-12 93 views
0

我無法弄清楚這個超簡單例子裏發生了什麼。Servlet --x - > Ajax:Ajax代碼沒有收到servlet響應

問題摘要:我有一個簡單的servlet,如果我手動驅動它,通過從瀏覽器發佈它的URL,似乎運行得很好。我的意思是:我可以在瀏覽器的HTML頁面看到我在servlet響應中寫入的任何東西。

但是,如果我通過Ajax代碼發出非常相同的URL,那麼servlet會很好地處理請求,甚至會'出現'寫出響應罰款......但是,我沒有看到任何響應在Ajax客戶端代碼端,因此也不在我的瀏覽器HTML頁面。

另外,如果我做我的XHR請求syncrhonous,瀏覽器錯誤控制檯顯示以下異常:

錯誤:未捕獲的異常:[異常...「組件返回故障代碼:0x80004005的(NS_ERROR_FAILURE) [nsIXMLHttpRequest.send]「nsresult:」0x80004005(NS_ERROR_FAILURE)「位置:」JS frame :: file:///home/sd/Desktop/test.html :: callServlet :: line 35「data:no]

環境:

瀏覽器:Firefox 3.5.3

Servlet容器:Tomcat的6.0.20

操作系統:Linux/Fedora的11

Ajax代碼:

<!-- test.html --> 
<html> 
<head> 
    <script> 
var req; 

function $(id) { 
    return document.getElementById(id); 
} 

function servletCallback() { 
    var field = $("debugHtmlId"); 
    field.innerHTML += "readyState='" + req.readyState + "'<br> "; 
    field.innerHTML += "status='" + req.status + "'<br> "; 
    field.innerHTML += "responseText='" + req.responseText + "' | <br> "; 
} 

req = new XMLHttpRequest(); 
req.onreadystatechange = servletCallback; 

    function callServlet() { 
     // With async mode off, I get the 
     // Exception listed above. 
     // req.open("GET", "http://localhost:8080/aaa/bbb?f=test", false); 

     req.open("GET", "http://localhost:8080/aaa/bbb?f=test", true); 
     req.send(null); 

    } 
    </script> 
</head> 
<body>  
    <input id="callserv" type="submit" value="Call Servlet" onclick="callServlet();" /> 
    <span id="debugHtmlId"></div> 
</body> 
</html> 

servlet代碼:

// servlet code 
public class MyServlet extends HttpServlet { 
    public void doGet(HttpServletRequest req, HttpServletResponse rsp) 
     throws ServletException, IOException { 

    rsp.setContentType("text/html"); 

    String val = req.getParameter("f"); 
    if(val.equals("test")) { 
     // Increment value. 
     ++_count; 

     // Return value. 
     PrintWriter out = rsp.getWriter(); 
     out.printf("%d\n", _count); 
     out.close(); 

     // This shows up fine in servlet log. 
     System.out.printf("%d\n", _count); 
    } 
    } 

    // This variable is incremented and returned on each call to doGet(). 
    private int _count = 0; 
} 

編輯:

  1. 包括結果:這是我看到的例子是我的我的debugHtmlId元素的innerHTML值。

    的readyState = '1' 的readyState = '1' 的readyState = '2' 狀態= '0' 的responseText = '' | readyState ='4' status ='0' responseText =''|

  2. 奇怪的行爲:還請注意我的readystatechange處理程序正在重新輸入!我的意思是,我期待看到readyState ='...'status ='...'responseText ='...'每個狀態變化的黑社會...

回答

1

問題是: 我在瀏覽器中加載了上述HTML,而不是從Tomcat/web服務器加載,而是從本地文件系統加載。我認爲,爲了開發,我不需要將HTML部署到服務器。

因爲我最初想要的東西現在工作得很好,所以我現在並不擔心我在ajax的同步模式中遇到的異常。

+1

關於您遇到的異常 - 只要將同步模式用於Ajax調用,Firefox確實會發生此錯誤,因爲發送同步請求會阻止執行並等待回覆,從而導致用戶界面無法響應。所以實際上,對於同步Ajax請求沒有任何有意義的用例場景。但是,其他瀏覽器如IE/Chrome /等。允許這種行爲而不會引發錯誤。 – Vuk 2010-01-17 22:20:45

0

試試這個:撥打PrintWriter致電out.close();。相反,請致電out.flush();

+0

已經嘗試過,從未工作過。實際上,我在某處讀到我們應該使用close()而不是flush()......否則,ajax方面仍然存在着更多內容正在出現的印象。這是原因,我用close()替換了flush()。 – Harry 2009-10-12 12:49:28

0

我看代碼,做了兩件事情與Tomcat5的對我的CentOS 5 Linux開發箱的工作:

  1. 修改了代碼,並重新命名我的servlet來eServlet:

    req.open("GET", "http://localhost:8080/aaa/bbb?f=test", true); 
    

    req.open("GET", "eServelet?f=test", true); 
    
  2. 改性WEB-INF/web.xml並加入servlet映射

    <servlet> 
        <servlet-name>eServletApps</servlet-name> 
        <servlet-class>eServlet</servlet-class> 
    </servlet> 
    
    <servlet-mapping> 
        <servlet-name>eServletApps</servlet-name> 
        <url-pattern>/eServlet</url-pattern> 
    </servlet-mapping> 
    
  3. 用命令編譯:

    # javac -classpath $CATALINA_HOME/common/lib/servlet-api.jar eServlet.java 
    
  4. 加載它和它的作品沒有任何問題

1

我是通過這個同樣的問題的工作。這絕對是一個跨域問題,在我的情況下,javascript文件與servlet是同一臺服務器,我正在下載並從一個不是的html頁面調用腳本。就像Harry一樣,我在本地加載html並獲得0狀態。

對我來說,解決辦法是添加

resp.addHeader(「訪問控制允許來源」,「*」);

到SERVLET代碼 - 這允許JavaScript從域外調用servlet。由於我知道servlet受到攻擊,服務器調試程序正在記錄GET,但它的響應是空的,狀態爲0,所以我殺了我,因爲問題中的所有代碼都可以正常工作,如果將此頭添加到servlets響應。