跨域和表单重复提交

一、跨域问题

  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);
    }
}
原文地址:https://www.cnblogs.com/mayuan01/p/12382472.html