2009-10-12 96 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响应。