Firebug: 已攔截跨源請求:同源策略禁止讀取位於XXX的遠程資源。(原因:CORS 頭缺少 'Access-Control-Allow-

第一種,就是在被請求的程序中添加HTTP頭,即CORS跨域(跨域資源共享,Cross-Origin Resource Sharing)

如: Response.Headers.Add("Access-Control-Allow-Origin", "*");
// JSON
{
  'Access-Control-Allow-Origin': '*', 
}
// HTML
<meta http-equiv="Access-Control-Allow-Origin" content="*">
// PHP
header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");

  添加此段代碼的目的很簡單,也就是告訴瀏覽器,這個資源是運行遠程所有域名訪問的。當然,此處的也可以替換爲指定的域名,出於安全考慮,建議將替換成指定的域名。
  由於IE10以下瀏覽器不支持CORS,所以目前在國內CORS並不是主流的跨域解決方案,但是隨着windows 10的發佈,IE的逐漸衰落,可以預見,在不遠的將來CORS將成爲跨域的標準解決方案。

第二種,就是在被請求的服務器上,添加HTTP響應頭。在這裏,我們就以IIS6.0爲例:

//在被請求的網站上,設置HTTP頭,添加
"Access-Control-Allow-Origin:*" //值爲*或指定的域名。

第三種,就是在被請求的服務器上在被請求的項目根目錄(root下)下放以下文件 :
crossdomain.xml

    <?xml version="1.0"?>    
    <!DOCTYPE cross-domain-policy SYSTEM "./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>    

cross-domain-policy.dtd

    <?xml version="1.0" encoding="ISO-8859-1"?>    
    <!-- Adobe DTD for cross-domain policy files -->    
    <!-- Copyright (c) 2008-2009, Adobe Systems Inc. -->    

    <!ELEMENT cross-domain-policy (site-control?,allow-access-from*,allow-http-request-headers-from*,allow-access-from-identity*)>    

    <!ELEMENT site-control EMPTY>    
    <!ATTLIST site-control permitted-cross-domain-policies (all|by-content-type|by-ftp-filename|master-only|none) #REQUIRED>    

    <!ELEMENT allow-access-from EMPTY>    
    <!ATTLIST allow-access-from domain CDATA #REQUIRED>    
    <!ATTLIST allow-access-from to-ports CDATA #IMPLIED>    
    <!ATTLIST allow-access-from secure (true|false) "true">    

    <!ELEMENT allow-http-request-headers-from EMPTY>    
    <!ATTLIST allow-http-request-headers-from domain CDATA #REQUIRED>    
    <!ATTLIST allow-http-request-headers-from headers CDATA #REQUIRED>    
    <!ATTLIST allow-http-request-headers-from secure (true|false) "true">    

    <!ELEMENT allow-access-from-identity (signatory)>    

    <!ELEMENT signatory (certificate)>    

    <!ELEMENT certificate EMPTY>    
    <!ATTLIST certificate fingerprint CDATA #REQUIRED>    
    <!ATTLIST certificate fingerprint-algorithm CDATA #REQUIRED>    

    <!-- End of file. -->    

第四種,使用JSONP格式
即在jQuery中ajax請求參數dataType:’JSONP’:

<script> 
    $.ajax({ 
        url:"http://map.oicqzone.com/gpsApi.php?lat=22.502412986242&lng=113.93832783228", 
        type:'GET', 
        dataType:'JSONP',  // 處理Ajax跨域問題
        success: function(data){ 
            $('body').append( "Name: " + data ); 
        } 
    }); 
</script>

或者:

    <script type="text/javascript">    
        function jsonpCallback(result){     
           alert(result[1].name);     
        }     
    </script>  
    <script type="text/javascript"src="http://localhost:8080/Jsonp/jsonp.jsp?callback=jsonpCallback"></script>  

或者jquery代碼:

    <script type="text/javascript">     
        $.getJSON("http://localhost:8080/Jsonp/jsonp.jsp?callback=?", function(json){      
            alert(json[0].name);     
        });     
     </script>  

後臺jsonp.jsp代碼:

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
    <%  
         String callback = request.getParameter("callback");  
         out.print(callback+"([ { name:'John',age:'19'},{ name:'joe',age:'20'}] );");  
         out.print(callback);  
    %>  

或者servlet

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet("/Jsonp")
public class Jsonp extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request,response);
    }

    /**
     * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
     */
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String jsonp=request.getParameter("jsonpcallback");  
        response.setContentType("text/html;charset=UTF-8");
        response.setCharacterEncoding("UTF-8");
        PrintWriter out = response.getWriter();
        out.write(jsonp + "0;null");
        out.close();
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }
}

ajax請求的參數:jsonp

類型:String
在一個 jsonp 請求中重寫回調函數的名字。這個值用來替代在 “callback=?” 這種 GET 或 POST 請求中 URL 參數裏的 “callback” 部分,比如 {jsonp:’onJsonPLoad’} 會導致將 “onJsonPLoad=?” 傳給服務器。

ajax請求的參數:jsonpCallback

類型:String
爲 jsonp 請求指定一個回調函數名。這個值將用來取代 jQuery 自動生成的隨機函數名。這主要用來讓 jQuery 生成度獨特的函數名,這樣管理請求更容易,也能方便地提供回調函數和錯誤處理。你也可以在想讓瀏覽器緩存 GET 請求的時候,指定這個回調函數名。

注意內容:
  1、Ajax請求需要設置請求類型爲Jsonp
  dataType: “jsonp”

  2、Ajax請求需要設置回調函數,當前函數值必須與服務器響應包含的callback名稱相同
  jsonpCallback:”fn”

  3、Ajax請求可以設置jsonp(可選),傳遞給請求處理程序或頁面,用以獲得jsonp回調函數名的參數名,默認爲:callback
  jsonp: “callback”

  4、服務端返回Json數據必須使用jsonpCallback設置的值進行包裹
  return “fn(“+JsonUtil.objectToJson(outPut)+”)”
  
第五種,使用Html5中新引進的window.postMessage方法來跨域傳送數據

CORS與JSONP相比,更爲先進、方便和可靠。

  1、 JSONP只能實現GET請求,而CORS支持所有類型的HTTP請求。
  
  2、 使用CORS,開發者可以使用普通的XMLHttpRequest發起請求和獲得數據,比起JSONP有更好的錯誤處理。
  
  3、 JSONP主要被老的瀏覽器支持,它們往往不支持CORS,而絕大多數現代瀏覽器都已經支持了CORS。
  
  對一個簡單的請求,沒有自定義頭部,要麼使用GET,要麼使用POST,它的主體是text/plain,請求用一個名叫Orgin的額外的頭部發送。Origin頭部包含請求頁面的頭部(協議,域名,端口),這樣服務器可以很容易的決定它是否應該提供響應。
  服務器端對於CORS的支持,主要就是通過設置Access-Control-Allow-Origin來進行的。
  Header set Access-Control-Allow-Origin *
  爲了防止XSS攻擊我們的服務器, 我們可以限制域,比如: Access-Control-Allow-Origin: http://blog.csdn.net
  很多服務都已經提供了CORS支持,比如 AWS 支持跨域資源分享功能CORS,向S3上傳不需要代理。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章