ajax跨域问题

跨域产生的原因

1、浏览器的限制

2、跨域,域名不一致,端口不一致

3、XHR(XMLHttpRequest)请求

三个同时存在才有可能产生跨域问题

解决跨域问题的思路

1、浏览器(通过指定参数让浏览器不去做校验,需要改动客户端,意义不大)

2、XHR(通过修改发出请求的类型,通过JSONP,动态创建script,在script中发送请求)

3、跨域

  a)修改被调用,让其支持跨域     b)修改调用方,隐藏跨域,使用代理

2.XHR方式

JSONP:JSON的扩充模式,在请求中增加一个约定的参数,用于识别请求是jsonp请求,后台识别到为jsonp的请求时,就以javascript的方式返回

前台请求使用jsonp,后台需要增加jsonp的切入

弊端:1、服务器需要改动    2、只支持get的方法    3、发送的不是XHR请求

    $.ajax({
            url:"http://127.0.0.1:8080/test/get1",
            dataType:"jsonp",
            jsonp:"callback2",
            success:function(result){
                console.log(result);
            }
        });
@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice{

    
    public JsonpAdvice() {
        super("callback2");
    }
    
}

3、跨域

跨域请求的请求头中,浏览器会增加Origin字段,保存原来的地址 

增加一个filter,为返回的时候在返回头中增加允许跨域的标识

public class CrosFilter implements Filter {

    @Override
    public void destroy() {
        // TODO Auto-generated method stub

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // TODO Auto-generated method stub
        HttpServletResponse httpResponse = (HttpServletResponse)response;
        
        //指定特定的域
//        httpResponse.addHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8090");
        //指定所有的域
        httpResponse.addHeader("Access-Control-Allow-Origin", "*");
                
        
        //指定特定的方法
//        httpResponse.addHeader("Access-Control-Allow-Methods", "GET");
        //指定所有的方法
        httpResponse.addHeader("Access-Control-Allow-Methods", "*");
        
        chain.doFilter(request, response);

    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        // TODO Auto-generated method stub

    }

}

请求分为两种:简单请求,非简单请求

简单请求:

1、方法为GET、POST、HEAD

2、请求HEAD里面无自定义头,ContentType为:text/plain、multipart/form-data、application/x-www-form-urlencoded

增加Filter在服务端解决跨域问题

public class CrosFilter implements Filter {

 

@Override

public void destroy() {

// TODO Auto-generated method stub

 

}

 

@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

throws IOException, ServletException {

// TODO Auto-generated method stub

HttpServletResponse httpResponse = (HttpServletResponse) response;

 

HttpServletRequest httpRequest = (HttpServletRequest) request;

 

String origin = httpRequest.getHeader("origin");

 

// 直接从request中获取并设置到response中

if (!"".equals(origin) && origin != null) {

httpResponse.addHeader("Access-Control-Allow-Origin", origin);

}

 

/*Enumeration enum1 = httpRequest.getHeaderNames();

 

System.out.println("-----------header----------------->");

while (enum1.hasMoreElements()) {

String key = (String) enum1.nextElement();

String value = httpRequest.getHeader(key);

System.out.println(key + ":" + value);

}

System.out.println("<-----------header-----------------");

 

String headers = httpRequest.getHeader("Access-Control-Request-Headers");

System.out.println("dd" + headers);

// 支持所有自定义的方法头

if (!"".equals(headers) && headers != null) {

httpResponse.addHeader("Access-Control-Allow-Headers", headers);

}

*/

 

// 指定特定的域,带cookie的请求需要全匹配

// httpResponse.addHeader("Access-Control-Allow-Origin",

// "http://127.0.0.1:8090");

// 带cookie请求时需要在请求头增加该参数值

httpResponse.addHeader("Access-Control-Allow-Credentials", "true");

// 指定所有的域,为*时不能满足带cookie的请求

// httpResponse.addHeader("Access-Control-Allow-Origin", "*");

// 指定特定的方法

// httpResponse.addHeader("Access-Control-Allow-Methods", "GET");

// 指定所有的方法

httpResponse.addHeader("Access-Control-Allow-Methods", "*");

// 当有options预检命令时

// httpResponse.addHeader("Access-Control-Allow-Headers",

// "Content-Type,x-header1,x-header2");

// 预检命令的缓存时间

httpResponse.addHeader("Access-Control-Max-Age", "3600");

 

chain.doFilter(request, response);

 

}

 

@Override

public void init(FilterConfig arg0) throws ServletException {

// TODO Auto-generated method stub

 

}

 

}

使用nginx解决跨域问题,增加一个nginx的配置文件

 apache解决跨域问题

使用spring框架解决跨域问题,在类或者方法上增加注解@CrossOrigin

原文地址:https://www.cnblogs.com/maple92/p/8707575.html