跨域和表单重复提交的一些解决方法

跨域

什么跨域:

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");

    }
}

  

原文地址:https://www.cnblogs.com/wishsaber/p/12269420.html