浏览器拦截表单提交的HTTP PUT请求,求排查提示
问题排查提示
问题背景
提交表单时页面无反应,Network面板显示PUT请求被拦截,涉及的代码如下:
HTML代码
<!DOCTYPE html> <html lang="pt-br"> <head> <meta charset="UTF-8"> <title>Contato</title> <link rel="stylesheet" href="style.css"> </head> <body> <nav class="navbar"> <a class="titulo" href="index.html">titulo 📧</a> </nav> <main> <form id="form"> <label for="nome">Nome</label> <input type="text" id="nome" name="nome" placeholder="Digite seu nome"> <label for="email">Email</label> <input type="email" id="email" name="email" placeholder="Digite seu email"> <label for="assunto">Assunto</label> <input type="text" id="assunto" name="assunto" placeholder="Digite o assunto"> <label for="mensagem">Mensagem</label> <textarea id="mensagem" name="mensagem" placeholder="Digite sua mensagem"></textarea> <label for="anexo">Anexo</label> <input type="file" id="anexo" name="anexo"> <button type="submit" onclick="submitForm('/mail/send');">Enviar</button> </form> </main> <script src="script.js"></script> </body> </html>
JavaScript代码
function submitForm(url) { const form = document.querySelector("#form"); fetch(url, { method: 'PUT', body: new FormData(form) }) .then(response => response.text()) .then(response => { var main = document.querySelector("main"); main.innerHTML = ''; if(response == '') { main.innerHTML = '<h1>Mensagem enviada com sucesso!</h1>'; } else { main.innerHTML = '<h1>Erro ao enviar mensagem! <small>'+response+'</small<</h1>'; } }) .catch(error => { console.error('Error:', error); }); }
Servlet代码
@WebServlet(name = "Send", urlPatterns = "/send") @MultipartConfig(maxFileSize = 1048576, maxRequestSize = 2097152) public class Send extends HttpServlet { ... protected void doPut(HttpServletRequest request, HttpServletResponse response) { ... } }
排查方向
阻止表单默认提交行为:按钮类型为
submit,点击会触发浏览器默认的表单提交(通常是GET/POST),直接中断你的Fetch请求。解决方法任选其一:- 把按钮类型改成
button:<button type="button" onclick="submitForm('/mail/send');">Enviar</button> - 在
submitForm函数中接收事件参数并阻止默认行为:function submitForm(url, event) { event.preventDefault(); ... },调用时传参:onclick="submitForm('/mail/send', event)" - 在
onclick中直接返回false:onclick="submitForm('/mail/send'); return false;"
- 把按钮类型改成
校验请求路径匹配:JS中请求路径是
/mail/send,但Servlet的urlPatterns是/send。需要确认:- 项目部署的上下文路径是否包含
/mail?如果没有,请求路径应改为/send - 查看Network面板中实际请求的URL,确认是否与Servlet的映射路径完全一致
- 项目部署的上下文路径是否包含
检查跨域(CORS)限制:如果前端页面和Servlet不在同一域名、端口或协议下,浏览器会拦截跨域PUT请求。需在Servlet的
doPut方法中添加CORS响应头:response.setHeader("Access-Control-Allow-Origin", "*"); // 或指定允许的具体域名 response.setHeader("Access-Control-Allow-Methods", "PUT, GET, POST, OPTIONS"); response.setHeader("Access-Control-Allow-Headers", "Content-Type");注意:带文件上传的PUT属于复杂请求,浏览器会先发送OPTIONS预检请求,需确保Servlet能处理OPTIONS请求(可重写
doOptions方法返回对应头)修复JS中的HTML语法错误:JS代码里的错误片段
</small<</h1>存在语法错误,应改为</small></h1>,这个错误会导致页面更新后无法正确渲染,可能让你误以为页面无反应检查Servlet的doPut方法实现:
- 确保
doPut方法没有抛出未捕获的异常,比如处理Multipart文件时是否正确获取Part对象 - 确认方法中设置了正确的响应状态码(成功时返回200,错误时返回4xx/5xx)
- 确保响应内容正确写入,比如
response.getWriter().write("错误信息");
- 确保
检查服务器安全配置:确认服务器(如Tomcat)是否允许PUT请求,有没有安全拦截器、防火墙或Web应用安全策略(如CSRF防护)阻止了PUT方法的请求
内容的提问来源于stack exchange,提问作者Kleber Mota
相关产品推荐
相关产品推荐

