第一種,就是在被請求的程序中添加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上傳不需要代理。
上線后最好把
Access-Control-Allow-Origin: *
的 * 改為允許訪問的特定域名
header('Access-Control-Allow-Origin:*'); header('Access-Control-Allow-Methods:HEAD,GET,POST,OPTIONS,PATCH,PUT,DELETE'); header('Access-Control-Allow-Headers:Origin,X-Requested-With,Authorization,Content-Type,Accept,Z-Key')
轉自:https://blog.csdn.net/xlxxcc/article/details/54588571