CROS跨域請求處理

1.什麼是跨域?

  跨域是指從一個域名的網頁去請求另外一個域名的資源。好比從www.baidu.com 頁面去請求 www.google.com 的資源。跨域的嚴格一點的定義是:只要 協議,域名,端口有任何一個的不一樣,就被看成是跨域html

2.爲何瀏覽器要限制跨域?

  緣由就是安全問題:若是一個網頁能夠隨意地訪問另一個網站的資源,那麼就有可能在客戶徹底不知情的狀況下出現安全問題。好比下面的操做就有安全問題:java

  1. 用戶訪問www.mybank.com ,登錄並進行網銀操做,這時cookie啥的都生成並存放在瀏覽器
  2. 用戶忽然想起件事,並迷迷糊糊地訪問了一個邪惡的網站 www.xiee.com
  3. 這時該網站就能夠在它的頁面中,拿到銀行的cookie,好比用戶名,登錄token等,而後發起對www.mybank.com 的操做。
  4. 若是這時瀏覽器不予限制,而且銀行也沒有作響應的安全處理的話,那麼用戶的信息有可能就這麼泄露了。

3.爲何要跨域?

  既然有安全問題,那爲何又要跨域呢? 有時公司內部有多個不一樣的子域,好比一個是location.company.com ,而應用是放在app.company.com , 這時想從 app.company.com去訪問 location.company.com 的資源就屬於跨域。jquery

4.實現跨域須要的技術手段。

  1.JSONP或者CORSweb

5.SpringMVC經過CORS實現跨域

  5.1定義一個Filterajax

package cn.ucmed.baseline.d2d.api.filter;

import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CorsFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
            // CORS "pre-flight" request
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
            response.addHeader("Access-Control-Max-Age", "1800");//30 min
        }
        //This will filter your requests and responses.
        filterChain.doFilter(request, response);
    }
}

  5.2在web.xml中配置這個filterspring

<filter>
    <filter-name>allowedAccessFilter</filter-name>
    <filter-class>cn.ucmed.baseline.d2d.api.filter.CorsFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>allowedAccessFilter</filter-name>
    <url-pattern>/registeryuyue/*</url-pattern>
</filter-mapping>

6.SpringBoot經過CORS實現跨域

package cn.ucmed.otaku;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ImportResource;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

@EnableZuulProxy
@SpringBootApplication(exclude = {
        DataSourceAutoConfiguration.class,
        HibernateJpaAutoConfiguration.class})
@ImportResource("classpath*:META-INF/spring/dubbo.xml")
public class GatewayApplication {

    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }

    @Bean
    public CorsFilter corsFilter() {

        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PATCH");
        config.addExposedHeader("token");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

7.jquery $.ajax()跨域請求獲取heads。

  ajax經過xhr.getAllResponseHeaders()能獲得全部response headers,經過xhr.getResponseHeader('token')能獲取到具體的head值,but,ajax跨域的請求getAllResponseHeaders()卻怎麼也獲取不到所有的head值,只能獲取到content-type這個head值,在http://stackoverflow.com/questions/15042439/cant-get-custom-http-header-response-from-ajax-getallresponseheaders終於找到了答案。須要在服務器端加 'Access-Control-Expose-Headers: header1,header2,header3'才能獲取到header1,header2,header3api

  $.ajax({
            type: "get",
            url: urlStr, //跨域的域名
            data: transmitModel,
            headers: {
                notice_str: randomStr,
                timestamp: timestamp,
                sign: signStr
            },
            success: function(data, status, xhr) {
                console.info(xhr.getAllResponseHeaders());
                console.info(xhr.getResponseHeader('token'))
                console.info(data);
                console.info(status);
            },
            error: function(e) {
                
            },
            complete: function() {
                
            }

        });

SpringMVC的Filter跨域

public class CorsFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
            // CORS "pre-flight" request
            response.addHeader("Access-Control-Allow-Origin", "*");
            response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
            response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
            response.addHeader("Access-Control-Max-Age", "1800");//30 min
            response.addHeader("Access-Control-Expose-Headers", "token");
        }
        //This will filter your requests and responses.
        filterChain.doFilter(request, response);
    }
}

SpringBoot的bean瀏覽器

  @Bean
    public CorsFilter corsFilter() {

        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        final CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("OPTIONS");
        config.addAllowedMethod("HEAD");
        config.addAllowedMethod("GET");
        config.addAllowedMethod("PUT");
        config.addAllowedMethod("POST");
        config.addAllowedMethod("DELETE");
        config.addAllowedMethod("PATCH");
        config.addExposedHeader("token");
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }

 

參考:

[1]博客,http://www.ruanyifeng.com/blog/2016/04/cors.html,跨資源共享CROS詳解安全

[2]博客,http://blog.csdn.net/notechsolution/article/details/50394391,跨域與跨域訪問

[3]博客,https://www.cnblogs.com/wwlhome/p/5787133.html,$.ajax應用之請求頭headers

[4]博客,http://www.qdfuns.com/notes/17001/6df913ad0788f32e6908d70c849b7b8e.html,如何獲取跨域請求的自定義response headers

相關文章
相關標籤/搜索