客戶端、服務端,跨域訪問設置


同源策略

同源策略,它是由Netscape提出的一個著名的安全策略。現在所有支持JavaScript 的瀏覽器都會使用這個策略。
  1. 協議相同
  2. 域名相同
  3. 端口相同

不同源的網頁之間,是無法互相訪問cookie、LocalStorage、indexDB的。

大家經常說的跨域訪問,CORS是一個W3C標准,全稱是"跨域資源共享"(Cross-origin resource sharing)。http://www.ruanyifeng.com/blog/2016/04/cors.html

跨域訪問時,如果客戶端發送非簡單請求,客戶端會首先發送一個option預請求,檢查服務端是否支持跨域訪問。

客戶端

一般客戶端指的是常見的瀏覽器。

1、使用原生XMLHttpRequest方式實現跨域訪問:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange=processResponse;
xhr.open("POST", "http://xxx.com/demo/index.php", true);  
xhr.withCredentials = true; //支持跨域發送cookies
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.send("id=1");

當跨域訪問需要傳輸被訪問域的cookie信息時,設置“xhr.withCredentials = true; ”,此時注意服務端的response header中也要增加header("Access-Control-Allow-Credentials: true"),具體原因稍后說明。

2、使用<script>標簽方式實現

var url = "http://xxx.com/demo/index.php?callback=callbackFunction"; 
var script = document.createElement('script');// 創建script標簽,設置其屬性
script.setAttribute('src', url);
document.getElementsByTagName('head')[0].appendChild(script);// 把script標簽加入head,此時調用開始

“callbackFunction”為需要回掉執行的函數,返回的是可執行的javscript代碼中以調用的方式出現,例如

callbackFunction({"name":"haha"})

使用script標簽實現跨域,會同時將目的域的cookie一並傳輸。

 

3、使用jquery的jsonp請求實現跨域訪問:

$.ajax({
    type: "get",
    dataType: "jsonp",
    url: 'http://xxx.com/demo/index.php',
    // jsonp: 'callback', //回調函數參數名
    // jsonpCallback: "callbackFunction",//用戶定義的callback函數,沒有定義的話會jQuery會自動生成以jQuery開頭的函數名
    success: function (json) {
        alert(json);
    }
});

使用jsonp方式實現看跨域,同使用<script>標簽的方式一樣。

如果指定了jsonpCallback,就不會執行success方法了;沒有指定jsonpCallback,會執行success。

注意,服務器返回的數據必須是可執行的javascript,使用指定的callback方法調用

// 如果指定了jsonpCallback為callbackFunction,返回應為是
callbackFunction({"name":"haha"})

// 如果沒有指定jsonpCallback,返回結果可能是
jQuery112403687357423576312_1487056485968({"name":"haha"})

 

4、使用jquery的普通ajax請求,實現跨域

$.ajax({
    type: "get",
    url: 'http://localhost/isv',
    xhrFields: { withCredentials: true }, //支持跨域發送cookie
    success: function (json) {
        alert(json);
    }
});

如果需要跨域發送cookie,增加xhrFields: { withCredentials: true },此時注意服務端的response header中也要增加header("Access-Control-Allow-Credentials: true"),具體原因稍后說明。

服務端[1]

需要跨域調用的url,在其返回的response header中,需要增加

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

代表響應所有跨域請求,多個值的話使用"|"分隔。如果response header中沒有此設置,瀏覽器在響應成功后,會阻止回調函數執行,拋出錯誤。

如果需要跨域訪問,request header中有cookie信息,並且

{ withCredentials: true }

服務端的response header中,需要增加

httpResponse.addHeader("Access-Control-Allow-Origin", "http://abc.com");
httpResponse.addHeader("Access-Control-Allow-Credentials", "true");

Access-Control-Allow-Origin不能再使用通配符。

 

tomcat實踐

web.xml中增加

<filter>
    <filter-name>CorssFilter</filter-name>
    <filter-class>com.abc.filter.CrossFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>CorssFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

編寫指定的filter

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class CrossFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
        httpResponse.addHeader("Access-Control-Allow-Origin", "*");
        // httpResponse.addHeader("Access-Control-Allow-Credentials", "true");
        filterChain.doFilter(servletRequest, servletResponse);
    }

    @Override
    public void destroy() {

    }
}

 

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

[2]. http://api.jquery.com/jquery.ajax/

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM