HTTP(“跨域问题”和“防止表单重复提交”)

一.跨域问题

  能够正常请求,但是没有办法获取到响应结果
解决方案一:设置请求头,在请求的资源中设置Access-Control-Allow-Origin请求头
//3.设置请求头
response.setHeader("Access-Control-Allow-Origin", "*");

解决方案二:.JSONP解决跨域问题
普通的跨域访问问题,浏览器会进行拦截,凡是src属性的都不会拦截
ajax:http://www.a.com:8080/a/AServlet

JSONP实现原理:动态加载<script>标签,利用src属性进行服务器资源的访问,但是只支持Get请求
1.在我们的Ajax请求当中,需要以JSONP方式请求(通过jquery手段,动态生成sript)

jsonp:"代表的时前台传给后台,后台再传递给你 jsonpCallBack"

2.再AJAX请求当中需要将返回的数据格式指定为jsonp

dataType:"JSONP"

3.JSONP需要以Get请求发送 ?username=zhangsan

4.后台需要做的事情:
1.正常接收数据

2.返回数据

前台传递过来的jsonp需要原路返回

String jsonp=request.getP("jsonpCallBack");

需要将返回的数据转换为JSON success

response.getWirter.write(jsonp+"("+返回的数据+")");

解决方案:
修改Ajax请求:
$("#button").click(function () {
//获取到文本框的值
var username=$("#username").val();
//发送Ajax请求www.a.com的A工程
$.ajax({
url:"http://www.a.com:8080/a/AServlet?username="+username,
type:"GET",
jsonp:"jsonpCallBack", //回调函数
dataType:"JSONP",
success:function (result) {
alert(result);
},
error:function () {
alert(‘系统错误~‘)
}
});
});

更改后台请求,需要将JSONP原路返回
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.接受数据
String username=request.getParameter("username");
System.out.println("接受的数据:"+username);

//接受Ajax传递的数据
String jsonpCallBack = request.getParameter("jsonpCallBack");
System.out.println("jsonpCallBack:"+jsonpCallBack);

String success = JSON.toJSONString("success");
//2.响应结果,数据必须为JSON格式
response.getWriter().write(jsonpCallBack+"("+success+")");
//3.设置请求头
/*response.setHeader("Access-Control-Allow-Origin", "*");*/
}
三.使用HTTPClient解决:就是不通过浏览器发送请求
B工程的页面发送的Ajax没有办法请求到A工程,因为浏览器会拦截,走后台,后台通过HTTPClient请求请求到A工程,获取到响应结果

1.B工程的Bindex.jsp页面请求到B工程的Servlet
$("#button").click(function () {
//获取到文本框的值
var username=$("#username").val();
//发送Ajax请求www.a.com的A工程
$.ajax({
url:"BServlet?username="+username,
type:"GET",
success:function (result) {
alert(result);
},
error:function () {
alert(‘系统错误~‘)
}
});
});
2.B工程的BServlet去模拟HTTP请求到A工程
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//内部通过HTTPClient进行转发
//构建一个连接
CloseableHttpClient client = HttpClients.createDefault();
//构建请求
HttpGet get=new HttpGet("http://www.a.com:8080/a/AServlet?username="+request.getParameter("username"));
//发送请求
CloseableHttpResponse httpResponse = client.execute(get);
//获取返回结果
String result = EntityUtils.toString(httpResponse.getEntity());
//将A工程响应结果给页面
response.getWriter().write(result);

}
3.A工程处理请求
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//1.接受数据
String username=request.getParameter("username");
System.out.println("接受的数据:"+username);

//2.响应结果
response.getWriter().write("success");

}

二.防止表单重复提交
1.网络延迟,再网络延迟时间内,频繁的提交表单
只能提交一次,监控表单的提交事件,通过一个boolean类型的变量来区分已经点击过还是没有点击,如果已经点击过,表单就不提交,没有点击过再提交

2.重新加载或者后退页面
思路如下:在我访问登录页面的时候,创建一个 Token令牌(当作一个标识) ,保存到session当中,然后再表单提交的时候将令牌一起提交
后台Servlet去判断session当中的令牌和表单提交的令牌是否相等,如果相等代表正常提交(session清空),如果不相等,代表非正常提交

Form.jsp页面
<body>
<form action="FormServlet" onsubmit="return formSubmit()" method="post">
<input type="hidden" id="hiddenToken" name="formToken"/>
<input type="text" name="username"/>
<input type="submit" value="提交"/>
</form>
</body>

<script type="text/javascript">
//创建一个变量 false代表没有点击过,true代表已经点击过
var flag=false;
function formSubmit() {
if(!flag){ //取反值为false
flag=true;
return true;
}else {
return false;
}
}

$(function () {
//生成令牌
$.ajax({
url:"TokenServlet",
type:"POST",
success:function (token) {
$("#hiddenToken").val(token);
}
})
})
</script>

TokenServlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//生成令牌
String token = UUID.randomUUID().toString();
//令牌保存到session当中
request.getSession().setAttribute("sessionToken",token);
//响应
response.getWriter().write(token);
}

FormServlet:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//验证令牌
//获取页面提交的隐藏域数据
String formToken = request.getParameter("formToken");
//获取Session中的Token
String sessionToken = (String)request.getSession().getAttribute("sessionToken");
//如果页面中获取的和session中不一致,代表已经提交过了,不要重复提交
if(!formToken.equals(sessionToken)){
response.getWriter().write("不要重复提交~");
return;
}

//接收数据
String username = request.getParameter("username");
System.out.println("接收的数据为:"+username);
//必须将token清空,不然永远是一致的
request.getSession().removeAttribute("sessionToken");

try {
//模拟网络延迟
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
//返回数据
response.getWriter().write("success");
}

原文地址:https://www.cnblogs.com/rzbwyj/p/12268989.html

时间: 2024-10-05 08:41:30

HTTP(“跨域问题”和“防止表单重复提交”)的相关文章

JSONP解决跨域问题,防止表单重复提交,防止XSS攻击

一.跨域问题:能够正常请求,但是没有办法获取到响应结果 解决方案一:设置请求头,在请求的资源中设置Access-Control-Allow-Origin请求头 //3.设置请求头 response.setHeader("Access-Control-Allow-Origin", "*"); 二.JSONP解决跨域问题 普通的跨域访问问题,浏览器会进行拦截,凡是src属性的都不会拦截 ajax:http://www.a.com:8080/a/AServlet JSON

跨域与防止表单重复提交

什么是跨域? 跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的. 广义的跨域: 1.) 资源跳转: A链接.重定向.表单提交 2.) 资源嵌入: <link>.<script>.<img>.<frame>等dom标签,还有样式中background:url().@font-face()等文件外链 3.) 脚本请求: js发起的ajax请求.dom和js对象的跨域操作等 其实我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场

跨域,防止表单重复提交

跨域1 <body> <input type="text" name="uname" id="uname"/> <input type="button" value="提交" id="button"/> </body> <script type="text/javascript" src="js/jque

防止表单重复提交

客户端防止表单重复提交: 不足之处:用户单击”刷新”,或单击”后退”再次提交表单,将导致表单重复提交 <script type="text/javascript"> //方式一 var iscommitted = false; function dosubmit(){ if(!iscommitted){ iscommitted = true; return true; }else{ return false; } } //方式二 function dosubmit(){ d

[原创]java WEB学习笔记34:Session 案例 之 解决表单重复提交

本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱好者,互联网技术发烧友 微博:伊直都在0221 QQ:951226918 ---------------------------------

[PHP]防止表单重复提交的几种方法

--------------------------------------------------------------------------------------------------- 1. 使用JS让按钮在点击一次后禁用(disable).=> 防止多次点击发生,实现方式较简单. 缺点:若客户端禁止JavaScript脚本,则失效. 2. 在提交成功后执行页面重定向(redirect).=> 转到提交成功信息页面. 特点:避免F5重复提交,消除浏览器前进和后退按导致的同样问题.

form表单重复提交问题

导致表单重复提交的原因是:第一次提交的表单会被缓存到内存中,直到页面下次提交或页面关闭或转向其他页面时才消失.在自调用返回时,内存中的数据依然在,这时页面中的判断提交的代码依然可以检测到提交的值,顾会产生重复提交的效果. 解决方法 Ⅰ重定向,页面提交后转到另一个页面而不是本页面 Ⅱ提交表单后提交按钮变灰/隐藏提交按钮 Ⅲ增加令牌token 访问页面前产生token public void toStart(HttpServletRequest req, HttpServletResponse re

如何防止表单重复提交

一.有很多的应用场景都会遇到重复提交问题,比如: 1.点击提交按钮两次.2.点击刷新按钮.3.使用浏览器后退按钮重复之前的操作,导致重复提交表单.4.使用浏览器历史记录重复提交表单.5.浏览器重复的 HTTP 请求. 二.防止表单重复提交的方法 1.禁掉提交按钮 表单提交后使用 Javascript 使提交按钮disable.这种方法防止心急的用户多次点击按钮.但有个问题,如果客户端把 Javascript 给禁止掉,这种方法就无效了. 2.Post/Redirect/Get 模式 在提交后执行

防止表单重复提交的几种策略

表单重复提交是在多用户Web应用中最常见.带来很多麻烦的一个问题.有很多的应用场景都会遇到重复提交问题,比如: 点击提交按钮两次. 点击刷新按钮. 使用浏览器后退按钮重复之前的操作,导致重复提交表单. 使用浏览器历史记录重复提交表单. 浏览器重复的HTTP请求. 几种防止表单重复提交的方法 禁掉提交按钮.表单提交后使用Javascript使提交按钮disable.这种方法防止心急的用户多次点击按钮.但有个问题,如果客户端把Javascript给禁止掉,这种方法就无效了. 我之前的文章曾说过用一些