【问题标题】:Servlet --x--> Ajax: Ajax code not receiving servlet responseServlet --x--> Ajax: Ajax 代码没有收到 servlet 响应
【发布时间】:2009-10-12 11:52:10
【问题描述】:

在这个极其简单的示例中,我无法弄清楚这里发生了什么。

问题摘要:我有一个简单的 servlet,如果我手动驱动它,它似乎运行得很好......通过从浏览器发出它的 URL。我所说的“很好”是指:我可以在浏览器 HTML 页面中看到我在 servlet 响应中写的任何内容。

然而,如果我通过 Ajax 代码发出相同的 URL,则 servlet 可以很好地处理请求,甚至“似乎”可以很好地写出响应......但是,我就是这样做的在 Ajax 客户端代码端没有看到任何响应,因此在我的浏览器 HTML 页面中也没有。

进一步,如果我将 XHR 请求同步,浏览器错误控制台会显示以下异常:

错误:未捕获的异常:[Exception...“组件返回失败代码:0x80004005 (NS_ERROR_FAILURE) [nsIXMLHttpRequest.send]”nsresult:“0x80004005 (NS_ERROR_FAILURE)”位置:“JS 框架 :: 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 的值。

    就绪状态='1' 就绪状态='1' 就绪状态='2' 状态='0' 响应文本='' | 就绪状态='4' 状态='0' 响应文本='' |

  2. 奇怪的行为:还要注意我的 readystatechange 处理程序正在重新进入!我的意思是,我期待在每次状态更改时看到 readyState='...' status='...' responseText='...' 三元组...

【问题讨论】:

    标签: ajax servlets xmlhttprequest responsetext


    【解决方案1】:

    问题是: 我不是从 Tomcat/Web 服务器而是从我的本地文件系统在我的浏览器中加载了上述 HTML。我想,为了开发,我不需要将 HTML 部署到服务器。

    由于我最初想要的现在工作正常,我现在并不担心我在 ajax 同步模式下遇到的异常。

    【讨论】:

    • 关于您得到的异常 - Firefox 确实会在将同步模式用于 Ajax 调用时给出此错误,因为发送同步请求会阻止执行并等待回复,从而使 UI 对用户无响应.因此,对于同步 Ajax 请求,实际上没有有意义的用例场景。但是,其他浏览器如 IE/Chrome/等。允许这种行为而不引发错误。
    【解决方案2】:

    我正在解决同样的问题。这绝对是一个跨域问题,在我的情况下,javascript 文件与 servlet 是同一台服务器,我正在下载并从一个不是的 html 页面调用脚本。就像哈利一样,我在本地加载 html 并获得 0 状态。

    我的解决方案是添加

    resp.addHeader("Access-Control-Allow-Origin", "*");

    到 SERVLET 代码 - 这允许 javascript 从域外调用 servlet。这让我很生气,因为我知道 servlet 受到攻击,服务器调试器正在记录 GET - 但响应为空且状态为 0。如果您将该标头添加到servlet 响应。

    【讨论】:

      【解决方案3】:

      试试这个:不要在PrintWriter 上拨打out.close();。相反,请致电out.flush();

      【讨论】:

      • 已经试过了,一直没用。事实上,我在某处读到我们应该使用 close() 而不是 flush() ......否则,ajax 方面仍然认为还有更多的东西在路上。这就是原因,我用 close() 替换了 flush()。
      【解决方案4】:

      我查看了代码并在我的 CentOS 5 Linux 开发盒上使用 Tomcat5 做了两件事:

      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. 加载成功,没有任何问题

      【讨论】:

        猜你喜欢
        • 2012-04-25
        • 2017-05-20
        • 1970-01-01
        • 2013-09-05
        • 1970-01-01
        • 2019-12-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多