Servlet--x--> Ajax:Ajax 代码未收到 servlet 响应

发布于 2024-08-06 23:48:34 字数 2750 浏览 8 评论 0原文

我无法弄清楚这个超级简单的例子中发生了什么。

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

但是,如果我通过 Ajax 代码发出完全相同的 URL,servlet 会很好地处理请求,甚至“看起来”会很好地写出响应......但是,只是我没有看到任何Ajax 客户端代码端的响应,因此在我的浏览器 HTML 页面中都没有响应。

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

错误:未捕获的异常:[异常...“组件返回失败代码:0x80004005 (NS_ERROR_FAILURE) [ nsIXMLHttpRequest.send]”nsresult:“0x80004005(NS_ERROR_FAILURE)”位置:“JS框架::file:///home/sd/Desktop/test.html::callServlet::第35行”数据:否]

环境:

浏览器: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='...' 三元组...

I'm unable to figure out what is going on here in this ultra simple example.

Problem Summary: I have a simple servlet that appears to run just fine if I drive it manually... by issuing its URL from the browser. By 'just fine' I mean: I can see in the browser HTML page whatever I write in the servlet response.

However, if I issue the very same URL via Ajax code, the servlet processes the request fine and even 'appears' to be writing out the response fine ... but, just that I do not see any response on the Ajax client code side and thus neither in my browser HTML page.

Further, if I make my XHR request syncrhonous, the browser error console shows the following exception:

Error: uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIXMLHttpRequest.send]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: file:///home/sd/Desktop/test.html :: callServlet :: line 35" data: no]

Environment:

Browser: Firefox 3.5.3

Servlet container: Tomcat 6.0.20

OS: Linux / Fedora 11

Ajax code:

<!-- 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 code:

// 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;
}

EDIT:

  1. Including the result: Here's what I see for example as the value of my innerHTML of my debugHtmlId element.

    readyState='1'
    readyState='1'
    readyState='2'
    status='0'
    responseText='' |
    readyState='4'
    status='0'
    responseText='' |

  2. Strange behavior: Notice also that my readystatechange handler is getting re-entered! I mean, I was expecting to see readyState='...' status='...' responseText='...' triads for every state change...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夏日浅笑〃 2024-08-13 23:48:34

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

由于我最初想要的现在工作得很好,所以我现在不太担心在 ajax 同步模式下遇到的异常。

The problem was:
I had loaded the above HTML in my browser not from the Tomcat/web server but from my local file system. I thought, for development I won't need to deploy the HTML to the server.

Since what I originally wanted works fine now, I'm not so worried now about the exception I was getting in the sync mode of ajax.

苏璃陌 2024-08-13 23:48:34

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

我的解决方案是添加

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

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

I was working through this same problem. It's definitely a cross domain issue and in my case the javascript file was the same server as the servlet and i was downloading and and calling the script from an html page that was not. Just like Harry I was loading the html locally and getting a 0 status.

The solution for me was to add

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

to the SERVLET code - this allows the javascript to call the servlet from outside the domain. It was killing me since i knew the servlet was getting hit, the server debugger was logging the GET - but the response was empty and the status was 0. all of the code on the question will work fine, if you add that header to the servlets response.

梦幻的心爱 2024-08-13 23:48:34

试试这个:不要在 PrintWriter 上调用 out.close();。相反,请调用 out.flush();

Try this: Don't call out.close(); on the PrintWriter. Instead, call out.flush();.

戏舞 2024-08-13 23:48:34

我查看了代码,并在使用 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 映射

    ;
        eServletApps
        eServlet
    
    
    
        eServletApps
        /eServlet
    
    
  3. 使用命令编译:

    # javac -classpath $CATALINA_HOME/common/lib/servlet-api.jar eServlet.java
    
  4. 加载它,它可以正常工作,没有任何问题

I look at the code and did two things to work on my CentOS 5 Linux dev box with Tomcat5:

  1. Modified the code and rename my servlet to eServlet:

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

    to

    req.open("GET", "eServelet?f=test", true);
    
  2. Modified WEB-INF/web.xml and added servlet mapping

    <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. Compiled with command:

    # javac -classpath $CATALINA_HOME/common/lib/servlet-api.jar eServlet.java
    
  4. Loaded it and it Works without any problems

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文