常见js跨域解决方案

戏子无情 提交于 2019-12-04 22:52:20

以下为几种常见js跨域解决方案:

ajax跨域请求

一、使用jsonp方式实现跨域请求

$.ajax({
        async: false, 
        type:"POST",
        dataType: 'jsonp', 
        //jsonp的值自定义,如果使用jsoncallback,那么服务器端,要返回一个jsoncallback的值对应的对象. 
        jsonp: 'jsoncallback', 
        url:rootPath+"/getXxx.json",
        data:{"resourceId": resourceId},
        success:function(result){
            //result是后端返回的业务值
        },
        error:function(data){
            alert('加载目录失败,请刷新尝试');
        }
    });

服务端代码:
    String callback = request.getParameter("jsoncallback");
    Gson gson = new Gson();
    return String.format("%s(%s)", callback,gson.toJson("结果"));

二、设置response响应头

@RequestMapping(value="getXxx")
@ResponseBody
public String getXxx(HttpServletResponse response){
    response.addHeader("Access-Control-Allow-Origin", "*");
    //业务代码
    Gson gson = new Gson();
    return gson.toJson("结果");
}

表示允许所有域访问该服务。

uploadify跨域上传 (flash跨域)

示例:A(www.a.com)站点的页面通过uploadify上传文件至站点B(www.b.com),解决办法是:在B站点的根路径下创建一个crossdomain.xml文件(www.b.com/crossdomain.xml可访问),crossdomain.xml的内容如下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cross-domain-policy SYSTEM  
    "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd" >  
<cross-domain-policy>  
    <site-control permitted-cross-domain-policies="all"/>  
    <allow-access-from domain="*"/>  
    <allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>
//如果是在https下,需配置<allow-access-from domain="*" secure="false"/>,该属性值指明信息是否经加密传输,当crossdomain.xml文件使用https加载时,secure默认设为true。此时将不允许flash传输非https加密内容。手工设置为false才允许flash传输非https加密内容。

原理:uploadify是使用flash来上传文件,跨域上传涉及到Flash的安全沙箱策略,Flash安全策略简单讲:同一个域的属于同一个沙箱,同一个沙箱的可以互相访问.如果要访问另外一个沙箱的内容就要在另外一个沙箱定义信任,这种信任策略就定义在crossdomain.xml中,以上代码表示B站信任所有域,任何其他域的flash都可以访问它,可以定义具体的网站地址以限制访问权限(不能省略端口)。
对于crossdomain.xml特别注意:这个文件的要放在站点的根目录下而且文件名固定在接收文件的服务器的根域名下提供crossdomain.xml文件
nginx内配置可参考

location / {
    set $flag  0;
    if ($request_uri ~* "^/xxx/.*$"){
        set $flag  1;
    }
    if ($request_uri ~* "^/crossdomain.xml$"){
        set $flag  1;
    }
    if ($flag = 0){
        rewrite ^(.*)$  https://www.xxx.com$1  permanent;
        break;
    }
    proxy_set_header    Host                 $host:80;
    proxy_set_header    X-Real-IP            $remote_addr;
    proxy_set_header    X-Forwarded-For      $remote_addr;
    proxy_pass     http://acg-licensing;
}

//路径非xxx和crossdomain.xml的重定向至https服务,这两个路径直接转至后端tomcat服务,将crossdomain.xml放至tomcat的更目录即可。

huploadify跨域上传文件

使用huploadify跨域上传文件时,直接在处理文件上传的方法里设置response.addHeader(“Access-Control-Allow-Origin”, “*”);仍然不能正常上传,监控网络请求,发现每次上传文件会有两个请求,第一个是一个options类型的请求,第二个才是上传文件的post请求。经过了解options请求相当于向服务端确认是否允许当前域访问该URL,所以我们需要额外提供一个方法其请求方式限制为options,放回跨域访问权限限制,代码如下

@RequestMapping(value = "upload",method=RequestMethod.OPTIONS)
public void uploadOptions(HttpServletRequest req, HttpServletResponse resp){
    resp.addHeader("Content-Type", "application/json;charset=UTF-8");
    resp.addHeader("Access-Control-Allow-Origin", "*");
    resp.addHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
}

但是添加后发现仍然不起效果,原来是springMVC默认不支持options方式,需要在web.xml内的DispatcherServlet中添加配置(加重字体部分),代码如下

<servlet>
    <servlet-name>spring-mvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    **<init-param>
        <param-name>dispatchOptionsRequest</param-name>
        <param-value>true</param-value>
    </init-param>**
    <load-on-startup>100</load-on-startup>
</servlet>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!