Сервлет --x -> Ajax: код Ajax не получает ответ сервлета - PullRequest
0 голосов
/ 12 октября 2009

Я не могу понять, что здесь происходит в этом ультра простом примере.

Описание проблемы: У меня есть простой сервлет, который, кажется, работает нормально, если я вожу его вручную ..., выдавая его URL из браузера. Под «просто отлично» я подразумеваю: я вижу в браузере HTML-страницу все, что пишу в ответе сервлета.

Однако , если я выдаю тот же URL-адрес с помощью кода Ajax, сервлет обрабатывает запрос нормально и даже «кажется» выписывает ответ нормально ... но, просто я этого не делаю увидеть любой ответ на стороне кода Ajax-клиента и, следовательно, ни на HTML-странице моего браузера.

Далее , если я сделаю мой запрос XHR синхронным, в консоли ошибок браузера отобразится следующее исключение:

Ошибка: необработанное исключение: [Exception ... »Компонент возвратил код ошибки: 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

Контейнер сервлетов: 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 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. Включая результат: вот что я вижу, например, как значение моего innerHTML моего элемента debugHtmlId.

    readyState = '1' readyState = '1' readyState = '2' статус = '0' responseText = '' | readyState = '4' статус = '0' responseText = '' |

  2. Странное поведение: обратите внимание также, что мой обработчик readystatechange получает повторный ввод ! Я имею в виду, я ожидал увидеть триады readyState = '...' status = '...' responseText = '...' для каждого изменения состояния ...

Ответы [ 4 ]

1 голос
/ 09 декабря 2011

Я работал над этой же проблемой. Это определенно междоменная проблема, и в моем случае файл javascript был тем же сервером, что и сервлет, и я загружал и вызывал скрипт с html-страницы, которой не было. Так же, как Гарри, я загружал html локально и получал статус 0.

Решением для меня было добавить

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

к коду SERVLET - это позволяет javascript вызывать сервлет из-за пределов домена. Это убивало меня, так как я знал, что сервлет получает удар, серверный отладчик регистрирует GET - но ответ был пустым, и статус был равен 0. Весь код в вопросе будет работать нормально, если вы добавите этот заголовок к ответ сервлетов.

1 голос
/ 21 октября 2009

Проблема была: Я загрузил приведенный выше HTML-код в браузер не с сервера Tomcat / Web, а с локальной файловой системы. Я подумал, что для разработки мне не нужно будет развертывать HTML на сервере.

Поскольку то, что я изначально хотел, теперь работает нормально, я теперь не очень беспокоюсь об исключении, которое я получаю в режиме синхронизации ajax.

0 голосов
/ 01 марта 2010

Я посмотрел код и сделал две вещи для работы с моим CentOS 5 Linux dev box с Tomcat5:

  1. Изменил код и переименовал мой сервлет в 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-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. Загрузил и все работает без проблем

0 голосов
/ 12 октября 2009

Попробуйте: не звоните out.close(); на PrintWriter. Вместо этого звоните out.flush();.

...