Изображение 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 и пропустит его через запрос изображения капчи. Под перезагрузкой я имею в виду только перезагрузить изображение, а не всю страницу.
Поможет ли какое-нибудь из этих предложений решить вашу проблему? Дайте мне отзыв об этом.