當您在DataV中使用API數據源時,可能會遇到跨域的問題。本文為您介紹跨域問題的產生背景,并提供幾種常見的解決跨域問題的方法。
背景信息
用戶A想創建一個可視化應用,用于向客戶展示數據。當數據源類型選擇API時,可能出現以下兩種情況。
若為遠程服務器上的API,則可以勾選服務器代理請求(因跨域無法訪問時可勾選)。勾選服務器代理請求(因跨域無法訪問時可勾選)時,由DataV后臺的服務器對API發起請求,超時時間為10秒,無法修改。
若為本地API,則不勾選服務器代理請求(因跨域無法訪問時可勾選),且接口需要進行跨域數據配置。不勾選服務器代理請求(因跨域無法訪問時可勾選)時,是由本地瀏覽器對該API進行訪問,超時時間由瀏覽器來決定。
什么是跨域數據配置
用戶A所包含的數據來自其自己的網站以及用戶B的網站。自己網站上的數據可以通過類似http://userA.com/page1
這樣的接口進行訪問。用戶B提供http://userB.com/page2
數據接口,但是當用戶A發送一個Javascript ajax請求到用戶B的網站上時,將無法獲得來自userB.com
的數據。
打開瀏覽器,您可以看到如下標記為紅色的文字 (Chrome)。 這意味著我們遇到了跨域問題。
XMLHttpRequest 無法加載 http://userB.com/page2。所請求的資源不帶有“Access-Control-Allow-Origin”報頭。因此不允許源站點“http://userA.com/page1/”進行訪問。
跨域問題形成的原因
由于每個網站都包含各種用戶接口、訂單接口和文章接口,這意味著每個人都可以將這些接口返回的數據放入自己的網站,甚至是實時放入。因此瀏覽器采用同源策略,用于限制一個源站點的腳本獲取其他源站點的資源。
同源:如果兩個頁面的協議(HTTP)、端口(80) 和主機(userA.com)相同,那么這兩個頁面被認為是來自同一個源。
解決方案
A.x.com和B.x.com跨域
如果兩個網站的子域不同,會存在跨域問題。例如
http://56.alibaba.com/
和http://trade.alibaba.com/
。在頁面中加入如下代碼,將該頁面聲明為更高級別的域。
<script> document.domain = "x.com"; </script>
JSONP
雖然JSONP是最經典、高效、瀏覽器兼容最好的解決方案,但由于它有非常高的跨站腳本攻擊風險,所以DataV不支持這種方式。您可查閱相關資料了解具體信息。
跨域資源共享
說明跨域資源共享:Cross Origin Resource Sharing,簡稱為CORS。已經與大多數較新的瀏覽器兼容。
基本原理:在源站點B(本地API)中加入自定義的HTTP頭部,使其他網站可以訪問其資源。
配置方法:
若源站點B的接口數據需要被某一個網站使用,在數據服務器返回的報頭信息中加入以下內容。
Access-Control-Allow-Origin: http://userA.com
若源站點B的接口數據需要被多個網站使用,必須使用一個程序來動態生成報頭信息。以PHP代碼為例。
<?php if (is_my_code($_SERVER['HTTP_ORIGIN'])) { header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}"); } ?>
若源站點B的接口數據需要被所用的網站使用,可以使用
“*”
。Access-Control-Allow-Origin: *
添加Cookie操作:默認情況下CORS中不包含Cookie信息。如果您想添加Cookie,可執行以下步驟。
添加
withCredentials
參數,以jQuery為例。$.ajax({ url: "http://userB.com/page2", xhrFields: { withCredentials: true } });
將服務器設置為允許使用報頭憑證,但不允許使用通配符
“*”
,以PHP為例。<?php if (is_my_code($_SERVER['HTTP_ORIGIN'])) { header("Access-Control-Allow-Origin: {$_SERVER['HTTP_ORIGIN']}"); // Disallow “*” header("Access-Control-Allow-Credentials:true"); } ?>
更多詳細信息請參見HTTP訪問控制(CORS)。