Servlet--x--> Ajax:Ajax 代码未收到 servlet 响应
我无法弄清楚这个超级简单的例子中发生了什么。
问题摘要: 我有一个简单的 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;
}
编辑:
包括结果:以下是我所看到的,例如我的 debugHtmlId 元素的innerHTML 的值。
就绪状态='1' 就绪状态='1' 就绪状态='2' 状态='0' 响应文本='' | 就绪状态='4' 状态='0' 响应文本='' |
奇怪的行为:另请注意,我的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:
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='' |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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题是:
我在浏览器中加载了上述 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.
我正在解决同样的问题。这绝对是一个跨域问题,在我的例子中,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.
试试这个:不要在
PrintWriter
上调用out.close();
。相反,请调用out.flush();
。Try this: Don't call
out.close();
on thePrintWriter
. Instead, callout.flush();
.我查看了代码,并在使用 Tomcat5 的 CentOS 5 Linux 开发盒上做了两件事:
修改了代码并将我的 servlet 重命名为 eServlet:
到
使用命令编译:
加载它,它可以正常工作,没有任何问题
I look at the code and did two things to work on my CentOS 5 Linux dev box with Tomcat5:
Modified the code and rename my servlet to eServlet:
to
Modified WEB-INF/web.xml and added servlet mapping
Compiled with command:
Loaded it and it Works without any problems