Изображение simplecaptcha подается только после перезагрузки

Я использую SimpleCaptcha для защиты нашей контактной формы. Работает хорошо, но только после перезагрузки страницы.

Сервлет это nl.captcha.servlet.StickyCaptchaServlet, поэтому он не должен менять изображение после перезагрузки. Но при первом открытии страницы изображение просто не загружается. Однако после перезагрузки все работает нормально.

web.xml

Капча обслуживается приложением, запущенным в /services,

<web-app>
  <servlet>
    <servlet-name>captcha</servlet-name>
    <servlet-class>nl.captcha.servlet.StickyCaptchaServlet<servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>captcha</servlet>
    <url-pattern>/captcha.png</url-pattern>
  </servlet-mapping>
</web-app>

HTML

<img src="/services/captcha.png">

сервер

я использую tomcat-7.0.34 на Windows 7 64bit машина с Java 1.7.0_07,

вопрос

Почему изображение появляется только после перезагрузки? Есть идеи?

4 ответа

Решение

Просто сделайте так, чтобы обойти то, что сказал emka86.

<img src="/services/captcha.png" style="display:none"> (Duplicate part to fix the issue)

<img src="/services/captcha.png"> (The actual one)

Надеюсь, это поможет любому будущему разработчику.

Есть несколько шагов, которые вы можете выполнить:

1> изменить web.xml добавить свой сервлет, который расширяет класс nl.captcha.servlet.StickyCaptchaServlet

 <servlet>   
    <description></description>    
    <display-name>CustomCaptchaServlet</display-name>    
    <servlet-name>CustomCaptchaServlet</servlet-name>    
    <servlet-class>org.example.servlets.CustomCaptchaServlet</servlet-class>    
 </servlet>    
  <servlet-mapping>    
    <servlet-name>CustomCaptchaServlet</servlet-name>    
    <url-pattern>/CustomCaptchaServlet</url-pattern>    
  </servlet-mapping>

2> CustomCaptchaServlet.java

package org.example.servlets;    
import static nl.captcha.Captcha.NAME;    

import java.io.IOException;    

import javax.servlet.ServletException;    
import javax.servlet.http.HttpServlet;    
import javax.servlet.http.HttpServletRequest;    
import javax.servlet.http.HttpServletResponse;    
import javax.servlet.http.HttpSession;    

import nl.captcha.Captcha;    
import nl.captcha.servlet.CaptchaServletUtil;    
import nl.captcha.servlet.StickyCaptchaServlet;    

public class CustomCaptchaServlet extends StickyCaptchaServlet {    
    private static final long serialVersionUID = 1L;    

    /**
     * @see StickyCaptchaServlet#StickyCaptchaServlet()
     */
    public CustomCaptchaServlet() {
        super();
        // TODO Auto-generated constructor stub
    }


    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    

        String _width = getServletConfig().getInitParameter("width");    
        String _height = getServletConfig().getInitParameter("height");    
        HttpSession session = request.getSession();    
        Captcha captcha;    
        if (session.getAttribute(NAME) == null) {    
            captcha = new Captcha.Builder(Integer.parseInt(_width), Integer.parseInt(_height))    
            .addText()    
            .gimp()    
            .addBorder()    
                .addNoise()    
                .addBackground()    
                .build();    
            session.setAttribute(NAME, captcha);    
            CaptchaServletUtil.writeImage(response, captcha.getImage());    
            return;    
        }    
        captcha = (Captcha) session.getAttribute(NAME);    
        CaptchaServletUtil.writeImage(response, captcha.getImage());    
    }    


    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {    

    }    

}    

Проверьте, что web.xml имеет captcha.png в то время как HTML имеет в виду captcha.jpg,

Это решает проблему?

Проблема в том, что StickyCaptchaServlet создает новое изображение капчи для сессии. Когда вы делаете первоначальный запрос к странице, у вас нет идентификатора сеанса, поэтому StickyCaptchaServlet не может соединить вас с каким-либо изображением, созданным для определенного сеанса.

После первого запроса основной сервлет создаст для вас сессию и отправит вам обратно какую-то sessionId, При следующем запросе (также перезагрузке) вы отправляете на сервер запрос с ранее полученным sessionId так что теперь ваш StickyCaptchaServlet Можно собрать изображение капчи для вашего сеанса, потому что он знает, что вы находитесь в любом сеансе.

Вы понимаете это объяснение? Будет ли это полезно для вас?

Добавлено после вашего вопроса, чтобы решить эту проблему.

Вы можете добавить в свой класс веб-приложения, которое будет реализовывать HttpSessionListener, Затем в методе sessionCreated Вы можете добавить запрос в StickyCaptchaServlet с только что созданным sessionId, В соответствии с StickyCaptchaServlet Док Вы просто должны призвать doGet метод с переданным ключом sessionId. После этого - когда браузер на вашей странице запросит URL /services/captcha.png он должен получить ответное изображение, созданное и подготовленное непосредственно перед вашим HttpSessionListener реализация.

Другой способ заключается в использовании сценариев на стороне клиента и после загрузки страницы без изображения, просто перезагрузите ее - при внутренней перезагрузке, например, JavaScript, браузер узнает sessionId и пропустит его через запрос изображения капчи. Под перезагрузкой я имею в виду только перезагрузить изображение, а не всю страницу.

Поможет ли какое-нибудь из этих предложений решить вашу проблему? Дайте мне отзыв об этом.

Другие вопросы по тегам