• 跨域及前后端分离


    最近总结了下常使用的跨域方案,希望对大家有用:

          因为浏览器的同源策略,浏览器实施安全限制,凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。关于跨域问题,提供以下目前常用的解决方案:

    一、       JSONP跨域请求

    1)        简介

    JSONP(JSON with Padding)是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题。

     

    2)     原理

    Script的src 不受同源策略的限,JSONP将JSON请求封装进一个                  JavaScript函数,作为脚本发回给浏览器。客户端加载时,该脚本不受限于同源策略,函数就像其中的JSON对象一样。

    3)         使用方法

    非统一框架项目

    ²  前端:

    若使用非框架的前端,推荐使用jQuery本身封装在ajax中的jsonp请求方法,在success回调函数中可获取正常json数据体。

     

    $.ajax({
        url: 'http://192.168.95.248:18080/jsonp/testJsonp',//请求地址
        dataType: "jsonp",
        jsonp: "callback", //传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为:callback)
        success: function (data) {
            console.log(data)
        }
    });
    
     

    ²  服务端:

    SpringMVC 4.1开始加入了对JSONP的支持,有两种实现方式:

    1. 配置方式
    <bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView">
    
        <property name="jsonpParameterNames">
    
            <set>
    
                <value>jsonp</value>
    
                <value>callback</value>
    
            </set>
    
        </property>
    
    </bean>
    1. 继承AbstractJsonpResponseBodyAdvice,对controller做处理
    @ControllerAdvice(basePackages = "com.github")
    
    public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
    
        public JsonpAdvice() {
    
            super("callback", "jsonp");
    
        }
    
    }

    返回数据结构:

     

    优缺点

    • 优点:

    兼容性好,适配绝大多数浏览器(保证兼容性IE8+),不需要XMLHttpRequest或ActiveX的支持;

    • 缺点:

    a)        只支持get请求而不支持post等其他类型的HTTP请求;

    b)      jsonp在调用失败的时候不会返回各种HTTP状态码;

    c)       要确定jsonp的请求是否失败并不容易,大多数框架的实现都是结合超时时间来          判定;

    二、Cors 前后端分离

    1)      简介

    CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。

    它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

    2)      原理

      CORS的基本原理是通过设置HTTP请求和返回中header,告知浏览器该请求是合法的,从而实现跨域。

    3)       使用方法

    ²  前端:

    发送cors请求 (已经在框架上对其进行封装,可直接使用)

     cors: function (options) {
                //设置jquery 支持跨域
                $.support && ($.support.cors = true);
                var config = $.extend({
                    type: 'post',
                    dataType: 'json',
                    crossDomain: true,
    
                    contentType: "application/json; charset=utf-8",
                    beforeSend: function (xhr) {
                        xhr.overrideMimeType("text/plain; charset=utf-8");
                    },
                    xhrFields: {
                        withCredentials: true
                    }
                }, options);
                if ($.support && $.support.msie) {
                    //为ie浏览器时增加xhrFields配置
                    config["xhrFields"] = { withCredentials: true };
                }
                $.ajax(config);
            },
    var corsConfig= {
        url: 'http://192.168.95.248:18081/test/hello4?page=1&size=10',//请求地址
        type: 'get', //请求方式
        dataType: 'json',//预期服务器返回的数据类型
        contentType: "application/json; charset=utf-8",//发送信息至服务器时内容编码类型
        beforeSend: function (xhr) {    //在发送请求之前调用,并且传入一个 XMLHttpRequest 作为参数
            xhr.overrideMimeType("text/plain; charset=utf-8");
        }
    }
    ajax.cors(corsConfig);

    IE8,9不兼容, withCredentials 特性在IE9及以下的版本也不会有实现。

    解决IE8,IE9兼容的方法:

    方案一:

    兼容IE8,9的插件

    https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest

    • 缺点:

    1.只能是GET 或是POST请求,在使用post时,数据总是发送一个 Content-Type 为text/plain,不能设置其他请求头部;

    2.只能是HTTP或者HTTPS,并且双方的协议需要一致;

    3.不支持Cookie的发送和接收;

    4.无法读写返回头部;

    方案二:

    IE开启设置:

     

     

    ²  服务端:

     3.1 配置文件

     config/*.properties

     

    web模块application.properties

     

    3.2 启动类

    加入CORS处理Filter

     

    b),优缺点

    优点:

    CORS支持所有类型的HTTP请求,可以使用普通的ajax实现跨域。

    缺点:

    1, 存在兼容性问题,IE10及以上才可正常发送请求

    2,  Cookie携带问题,IE8,9用户手动设置浏览器,才可以支持正常的cookie发送和接受;

     

    CORS本身协议支持IE8+ , Firefox5+, Chrome12+, Safari4+,移动端几乎全支持。但在较早版本(8 和 9)中,CORS 机制是借由 XDomainRequest 对象完成的,所以在IE8,9中也无法通过XmlHttpRequest2 的属性”withCredentials”携带cookie。

    三、使用Nginx反向代理

    1) 简介

    nginx  是一个高性能的HTTP反向代理服务器,特点是占有内存少,并发能力强,事实上nginx的并发能力确实在同类型的网页服务器中表现较好。

    2) 原理

    Nginx可作为反向代理服务器把http请求转发到另一个或者一些服务器上,将本地一个url前缀映射到要跨域访问的web服务器上,也就是,将对后端请求映射到某一路径,然后在Nginx内配置将该路径的请求重写到真正的后端服务所在。就可以实现跨域访问。

    3) 配置方法

    跨域解决的方案:简易配置示例:

    server {
        listen       9980;
        server_name  localhost;
    
        location / {
        #前端页面地址
    proxy_pass   http://localhost:8892; 
    }
    location ^~/apis {
    rewrite  ^/apis/(.*)$ /$1 break;
    #后端服务地址
    proxy_pass   http://localhost:18081;
    }

    具体说明:

    配置了一个/apis的拦截,把所有/apis/**的请求进行重写,比如/apis/hello4?page=1&size=12会重写到真正的后端服务地址http://localhost:18081/hello4?page=1&size=12,由于前后端都是在localhost: 9980下,就不存在跨域问题。

    参考资源:

    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

    https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest

    https://stackoverflow.com/questions/10232017/ie9-jquery-ajax-with-cors-returns-access-is-denied

    https://stackoverflow.com/questions/3362474/jquery-ajax-fails-in-ie-on-cross-domain-calls

    前后端分离,目前想使用这种方式,还未实践

  • 相关阅读:
    [转]MYSQL5.7版本sql_mode=only_full_group_by问题
    [坑]Linux MySQL环境表名默认区分大小写
    [转]CentOS 7.3 安装MySQL
    [转]Oracle截取字符串相关函数
    服务相关
    CSRF攻击
    sqlalchemy——多表操作
    sqlalchemy——基本操作
    高可用——网站运行监控
    高可用——软件质量保证
  • 原文地址:https://www.cnblogs.com/fnncat/p/7085302.html
Copyright © 2020-2023  润新知