跨域
什么跨域:
AJAX 跨域访问是用户访问A网站时所产生的对B网站的跨域访问请求均提交到A网站的指定页面
由于安全方面的原因, 客户端js使用xmlhttprequest只能用来向来源网站发送请求,比如在www.readlog.cn下去请求test.readlog.cn的数据,都是不行的
解决方法:
一:请求头解决
请求端
<%--
Created by IntelliJ IDEA.
User: wish
Date: 2020/2/6
Time: 16:08
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<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请求www.a.com的A工程
$.ajax({
url:"http://www.two.com:8080/HeadAServlet",
data:{"userName":username},
type:"POST",
success:function (result) {
alert(result);
},
error:function () {
alert('系统错误~')
}
});
});
});
</script>
</head>
<body>
<input type="text" name="username" id="username"/>
<br/>
<input type="button" id="button" value="请求"/>
</body>
</html>
响应端
package com.wish;
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("/HeadAServlet")
public class HeadAServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//設置請求頭
resp.setHeader("Access-Control-Allow-Origin", "*");
//获取数据
String userName =req.getParameter("userName");
System.out.println("接受的数据:"+userName);
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write("服务器正确接收到数据");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
}
二:JSONP解决
请求端
<%--
Created by IntelliJ IDEA.
User: wish
Date: 2020/2/6
Time: 16:08
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>模拟跨域_JSONP解决</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script>
$(function(){
$("#button").click(function () {
//获取到文本框的值
var username=$("#username").val();
//发送Ajax请求www.a.com的A工程
$.ajax({
url:"http://www.two.com:8080/JSONPServlet?userName="+username+"",
type:"GET",
jsonp:"jsonpCallBack", //回调函数
dataType:"JSONP",
success:function (result) {
alert(result);
},
error:function () {
alert('系统错误~')
}
});
});
});
</script>
</head>
<body>
<input type="text" name="username" id="username"/>
<br/>
<input type="button" id="button" value="请求"/>
</body>
</html>
响应端
package com.wish;
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("/JSONPServlet")
public class JSONPServlet 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 {
//获取数据
resp.setContentType("text/html;charset=utf-8");
String userName =req.getParameter("userName");
System.out.println("接受的数据:"+userName);
//接受Ajax传递的数据
String jsonpCallBack = req.getParameter("jsonpCallBack");
System.out.println("jsonpCallBack:"+jsonpCallBack);
String success = JSON.toJSONString("服务器正确接收到数据");
//响应结果,数据必须为JSON格式
resp.getWriter().write(jsonpCallBack+"("+success+")");
}
}
三:HTTPClient解决
请求端
页面
<%--
Created by IntelliJ IDEA.
User: wish
Date: 2020/2/6
Time: 16:11
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>模拟跨域_HTTPClient解决</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<script>
$(function () {
$("#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('系统错误~')
}
});
});
})
</script>
</head>
<body>
<input type="text" name="username" id="username"/>
<br/>
<input type="button" id="button" value="请求"/>
</body>
</html>
后台
package com.wish;
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 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("/BServlet")
public class BServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//内部通过HTTPClient进行转发
//构建一个连接
CloseableHttpClient client = HttpClients.createDefault();
//构建请求
HttpGet get=new HttpGet("http://www.two.com:8080/HTTPClientServlet?userName="+request.getParameter("username"));
//发送请求
CloseableHttpResponse httpResponse = client.execute(get);
//获取返回结果
String result = EntityUtils.toString(httpResponse.getEntity());
//将A工程响应结果给页面
response.getWriter().write(result);
}
}
响应端
package com.wish;
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("/HTTPClientServlet")
public class HTTPClientServlet 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 {
//获取数据
resp.setContentType("text/html;charset=utf-8");
String userName =req.getParameter("userName");
System.out.println("接受的数据:"+userName);
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write("服务器正确接收到数据");
}
}
表单重复提交
什么是表单的重复提交
在表单提交到一个Servlet ,而Servlet 又通过请求转发的方式响应一个JSP(HTML) 页面, 这个时候地址栏显示的是Servlet的路劲,
在刷新页面,这个时候会造成表单的重复提交。
在响应页面没有到达时候重复点击“提交按钮”,会造成表单的重复提交。
你在响应页面时候点击返回,在点击提交按钮的时候,会造成表单的重复提交。
解决方法
页面
<%--
Created by IntelliJ IDEA.
User: wish
Date: 2020/2/6
Time: 16:08
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script type="text/javascript" src="js/jquery-1.8.3.min.js"></script>
<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>
</head>
<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>
</html>
生成前台的Token令牌
package com.wish;
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 {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
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);
}
}
后台服务
package com.wish;
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("/FormServlet")
public class FormServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
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.setContentType("text/html;charset=utf-8");
//返回数据
response.getWriter().write("success");
}
}
浙公网安备 33010602011771号