ajax的跨域解决方案(java+ajax)

简单的建立一个后台项目

新建servlet:

内容如下:

package a;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
      System.out.println("执行了一个跨域请求"); response.setContentType(
"text/plain;charset=utf-8"); PrintWriter out = response.getWriter(); out.println("success"); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }

web.xml

<servlet>
    <servlet-name>TestServlet</servlet-name>
    <servlet-class>a.TestServlet</servlet-class>
  </servlet>

  <servlet-mapping>
    <servlet-name>TestServlet</servlet-name>
    <url-pattern>/s/t</url-pattern>
  </servlet-mapping>

前端代码:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <button onclick="goAjax()">ajax</button>
    </body>
    <script type="text/javascript" src="js/jquery-2.1.4.js" ></script>
    <script type="text/javascript">
        function goAjax(){
            $.ajax({
                url:"http://192.168.0.102:8080/a/s/t",
                type:"get",
                success:function(data){
                    console.log(data);
                }
            });
        }
    </script>
</html>

运行前后台项目,出现异常情况

在查看ajax的发送情况

从这里可以看到结果是正确返回的;并且后台也是正常执行了。

因此得出结论:

跨域是浏览器在aja返回结果的时候进行了拦截,先执行,后判断,不是后台不允许跨域;

客户端建立一条img标签,地址是刚才的ajax地址

<img src="http://192.168.0.102:8080/a/s/t" />

查看请求

查看请求,依然是成功的。

结论:跨域只发生在xmlHttpRequest对象上,通俗点说就是发生在ajax上。

浏览器从我们的请求路径中解析出我们的ajax请求的主机信息,得知是跨域请求,就会给请求头添加一个origin头信息。

我们可以在返回的时候添加一个响应头,来通过浏览器对跨域拦截。

1.通过修改后台代码实现跨域

添加过滤器CrossFilter.java

package a;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


public class CrossFilter implements Filter{
    @Override
    public void destroy() {}

    @Override
    public void doFilter(ServletRequest req, ServletResponse res,
            FilterChain doChain) throws IOException, ServletException {
        HttpServletRequest request=(HttpServletRequest) req;
        HttpServletResponse response=(HttpServletResponse)res;
        request.setCharacterEncoding("utf-8");
        //response.setContentType("text/plain;charset=utf-8");
        //response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8020");或者
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "*");//GET  POST
        //response.setHeader("Access-Control-Allow-Headers","content-type");
        //跨域预检缓存
        response.setHeader("Access-Control-Max-Age","3600");
        doChain.doFilter(req,res);
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        
    }

}

web.xml

<filter>
        <filter-name>CrossFilter</filter-name>
        <filter-class>a.CrossFilter</filter-class>
    </filter>
    <filter-mapping>
         <filter-name>CrossFilter</filter-name>
            <url-pattern>/*</url-pattern>
    </filter-mapping>

现在已经可以实现跨域请求了。

简单请求:

  1.get,head,post

  2.请求header里面

    1)无自定义头

    2)Content-Type为以下几种:text/plain,multipart/form-data,application/x-www-form-urlencoded.

非简单请求

  1.put,delete方法的ajax请求

  2.发送json字符串格式的ajax请求

  3.带自定义头的ajax请求

ajax发送非简单请求的时候,会出现请求不通的情况

$.ajax({
                url:"http://192.168.0.102:8080/a/s/t",
                type:"post",
                contentType:"application/json",
                data:JSON.stringify({name:"gys"}),
                success:function(data){
                    console.log(data);
                }
            });

结合上面的提示我们给过滤器添加一条头部信息。

重新运行,跨域问题解决,查看请求的时候发现,一个ajax请求发送了两边。

第一条是一条预检请求,这个请求是在发生非简单请求时,检查跨域请求是否能被通过。

如果每次请求都这样预检一次,会非常耗费网络资源,影响我们的请求速度。

可以在过滤器端添加一个预检缓存。

现在只有第一次请求的时候会出现预检请求,后面的就没有了。

可是我现在想要恢复预检请求,把预检代码注释了,可是还没到预检请求的缓存时间,同样没有办法查看到预检请求。

可以勾选谷歌浏览器的Disable cache

晚上回来继续编写下面的内容

nginx的转发,实现跨域

nginx的配置反响代理,实现跨域。

猜你喜欢

转载自www.cnblogs.com/guoyansi19900907/p/8949348.html