跨域和表单重复提交
一、跨域问题
1、方案一:HTTP请求头
AServlet
import com.alibaba.fastjson.JSON;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/aServlet")
public class AServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
//方法一:使用请求头解决跨域问题
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
System.out.println("数据:"+username);
//响应
resp.getWriter().write("success");
//添加请求头方式解决跨域
resp.setHeader("Access-Control-Allow-Origin","*");
}
}
Bindexjsp
<html>
<head>
<title>跨域</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script>
//使用请求头解决跨域问题
$(function () {
$("#button").click(function () {
var username=$("#username").val();
$.ajax({
url:"http://www.aproject.com:8080/aServlet",
data:{"username":username},
type:"POST",
success:function (result) {
alert(result)
},
error:function () {
alert("error!!!")
}
})
})
})</script>
</head>
<body>
<input type="text" name="username" id="username"/><button id="button" type="button">提交</button>
</body>
</html>
2、方案二:JSONP
前端代码
<html>
<head>
<title>跨域</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script>
//使用JSONP方式解决跨域问题
$(function () {
$("#button").click(function () {
var username=$("#username").val();
$.ajax({
url:"http://www.aproject.com:8080/aServlet?username="+username,
type:"GET",
jsonp:"jsonp", //回调函数
dataType:"JSONP",
success:function (result) {
alert(result)
},
error:function () {
alert("error!!!")
}
})
})
})</script>
</head>
<body>
<input type="text" name="username" id="username"/><button id="button" type="button">提交</button>
</body>
</html>
AServlet代码
import com.alibaba.fastjson.JSON;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/aServlet")
public class AServlet extends HttpServlet {
//resp.setContentType("text/html;charset=utf-8");
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
//方法二:使用JSONP解决跨域问题
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
System.out.println("数据:"+username);
//使用JSONP解决跨域问题
String jsonp = req.getParameter("jsonp");
//需要将返回的数据转换为JSON格式
String success = JSON.toJSONString("success");
resp.getWriter().write(jsonp+"("+success+")");
}
}
JSONP的优点:它不像是XMLHttpRequest对象实现的ajax请求那样受到同源策略的限制,它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持,并且在请求完毕后可以通过调用callback的方式回传结果;
JSONP的缺点:它只支持GET请求而不支持POST等其他类型的HTTP请求,它只支持跨域HTTP请求这种情况下,不能解决不同域的两个页面之间如何进行JavaScript调用的问题;
3、方案三:HTTPClient
前端代码
<html>
<head>
<title>跨域</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script>
//使用HttpClient方式解决跨域问题
$(function () {
$("#button").click(function () {
var username=$("#username").val();
$.ajax({
url:"httpServlet?username="+username,
type:"GET",
success:function (result) {
alert(result)
},
error:function () {
alert("error!!!")
}
})
})
})
</script>
</head>
<body>
<input type="text" name="username" id="username"/><button id="button" type="button">提交</button>
</body>
</html>
HTTPClient端代码
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import sun.net.www.http.HttpClient;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/httpServlet")
public class HttpCient extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建连接
CloseableHttpClient client = HttpClients.createDefault();
//请求
HttpGet httpGet=new HttpGet("http://www.aproject.com:8080/aServlet?username="+req.getParameter("username"));
//发送请求
CloseableHttpResponse response = client.execute(httpGet);
//获取返回结果 将A工程中的success提示语句返回给httpClient
String s = EntityUtils.toString(response.getEntity());
//响应 HttpClient将返回的结果响应给页面
resp.getWriter().write(s);
}
}
AServlet端
import com.alibaba.fastjson.JSON;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/aServlet")
public class AServlet extends HttpServlet {
//resp.setContentType("text/html;charset=utf-8");
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
//方法三:使用HttpClient解决跨域问题
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
System.out.println("数据:"+username);
//响应
resp.getWriter().write("success");
}
}
4、方案四:Nginx
前端代码
server {
listen 80;
server_name www.nginx.com;
location /A {
proxy_pass http://www.aproject.com:8080;
index index.html index.htm;
}
location /B {
proxy_pass http://www.bproject.com:8081;
index index.html index.htm;
}
}
二、表单重复问题
前端代码
<html>
<head>
<title>表单重复提交</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script>
var isFlag=false; //表单是否已经提交标识,false代表没有点击过,true代表点击过
function submitFlag() {
if (!isFlag){ //取反值
isFlag=true;
return true;
} else{
return false;
}
}
//token令牌
$(function () {
//生成令牌
$.ajax({
url:"tokenServlet",
type:"POST",
success:function (token) {
$("#token").val(token);
}
})
})
</script>
</head>
<body>
<form action="submitServlet" onsubmit="return submitFlag()" method="post">
<input type="hidden" id="token" name="token" />
用户名:<input type="text" name="username" />
<button type="submit">提交</button>
</form>
</body>
</html>
token类:
package com.wn;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;
@WebServlet("/tokenServlet")
public class TokenServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//生成令牌
String token = UUID.randomUUID().toString();
//令牌保存到session当中
req.getSession().setAttribute("token",token);
//将生成的令牌响应给页面
resp.getWriter().write(token);
}
}
SubmitServlet 代码:
package com.wn;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/submitServlet")
public class SubmitServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取页面中的token令牌
String token = req.getParameter("token");
//获取session中的token令牌
String token1 = (String) req.getSession().getAttribute("token");
//将页面获取的token令牌与session中的token令牌比较是否一致
//如果不一致代表补不能重复提交,如果一致则走下面的操作
if (!token.equals(token1)){
resp.setContentType("text/html;charset=utf-8");
resp.setCharacterEncoding("UTF-8");
resp.getWriter().write("数据不能重复提交error!");
return;
}
//接收页面的username属性值
String username = new String (req.getParameter("username").getBytes("ISO-8859-1"),"UTF-8");
System.out.println("数据:"+username);
// //请求session中的值
req.getSession().removeAttribute("token");
try {
//模拟网络延迟
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//响应数据
resp.getWriter().write("success");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
}



浙公网安备 33010602011771号