2009-10-12 1 views
0

Я не могу понять, что происходит здесь, на этом ультрапростом примере.Servlet --x -> Ajax: код Ajax не получает ответ сервлета

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

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

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

Ошибка: неперехваченное исключение: [Exception ... «Компонент возвращается код ошибки: 0x80004005 (NS_ERROR_FAILURE) [nsIXMLHttpRequest.send] "nsresult:" 0x80004005 (NS_ERROR_FAILURE) "location:" JS frame :: file: ///home/sd/Desktop/test.html :: callServlet :: строка 35 "data: no]

Окружающая среда:

Browser: 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 код:

// 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' status = '0' responseText = '' |

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

ответ

1

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

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

+1

Что касается исключения, которое вы получали - Firefox действительно дает эту ошибку всякий раз, когда режим синхронизации используется для вызовов Ajax, потому что отправка запроса синхронизации блокирует выполнение и ждет ответа, что делает пользовательский интерфейс неприемлемым для пользователя. Таким образом, практически не существует значимого сценария использования для запроса Ajax синхронизации. Тем не менее, другие браузеры, такие как IE/Chrome/etc. разрешить это поведение, не вызывая ошибки. – Vuk

0

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

+0

Пробовал уже, никогда не работал. На самом деле, я где-то читал, что мы должны использовать close(), а не флеш() ... в противном случае сторона ajax остается под впечатлением, что больше вещей в пути. Вот почему я заменил flush() на close(). – Harry

0

Я смотрю на код и сделал две вещи, чтобы работать на моем Dev поле CentOS 5 Linux с 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. Loaded его, и он работает без каких-либо проблем

1

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

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^