說到跨域,就必須要知道同源策略.以下是來自百度百科的解釋:同源策略(Same origin policy)是一種約定,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,則瀏覽器的正常功能可能都會受到影響; 可以說Web是構建在同源策略基礎之上的,瀏覽器只是針對同源策略的一種實現。
同源意味着域名, 端口, 協議必須保持完全一致, 否則無法通信.
好了, 問題來了. web前端愈加複雜的今天, 模塊化, 耦合性低, 體積愈加龐大等等因素, 都迫使我們要將前端分割成幾大塊, 實現按需加載. 而此時, 受到同源策略影響, 頁面之間通信成了一個必須解決的問題—我們稱之爲跨域
本人才疏學淺, 只知道三種解決方案:
方案一: 後臺(PHP)在非同源網站拉取數據, 解析(比如爬蟲什麼的)
方案二: jsonp(這個都很熟悉了)
方案三: HTML5新的API—POSTMessage
方案一, 比如獲取’http://36kr.com/feed‘這個新聞開放接口裏面的數據.主要工作其實在後臺(PHP).總共有兩個PHP文件: superClass.php 和 readXML.php. 前者用於創建父類, 後者用於解析接口裏面的XML數據並傳遞給前端.
superClass.php
<?php
class superClass{
private $obj;
function __construct(array $arguments = array()){
if (!empty($arguments)) {
foreach ($arguments as $property => $argument) {
$this->$property = $argument;
}
}
}
}
?>
創建父類的代碼可以說是萬用的, 我也不是太理解, 所以沒法說更多.重點看下readXML.php這個文件
<?php
require_once 'superClass.php';
$xml = new DOMDocument(); //創建空XML文檔
$xml->load('http://36kr.com/feed'); //加載數據
$main = $xml->getElementsByTagName('item'); //獲取所有數據
$i = 0; //一次請求拉取10條數據
$arrObj =Array(); //對象裝進數組
foreach( $main as $mainEach)
{ //獲取逐條數據
if ($i++ == 10) {
echo json_encode($arrObj); //傳給前端頁面
break;
}
$childrenClass = new superClass(); //實例化父類
// 作者
$author = $mainEach->getElementsByTagName( "author" );
foreach ( $author as $authorEach )
{
$value = $authorEach->firstChild->nodeValue;
$childrenClass->author = $value;
}
// 標題
$title = $mainEach->getElementsByTagName( "title" );
foreach ( $title as $titleEach )
{
$value = $titleEach->firstChild->nodeValue;
$childrenClass->title = $value;
}
// 分類
$category = $mainEach->getElementsByTagName("category");
foreach ($category as $categoryEach) {
$value = $categoryEach->firstChild->nodeValue;
$childrenClass->category = $value;
}
// 詳細內容
$description = $mainEach->getElementsByTagName( "description" );
foreach ( $description as $descriptionEach )
{
$value = $descriptionEach->firstChild->nodeValue;
$childrenClass->description = $value;
}
// 新聞發佈時間
$pubDate = $mainEach->getElementsByTagName( "pubDate" );
foreach ( $pubDate as $pubDateEach )
{
$value = $pubDateEach->firstChild->nodeValue;
$monthStr = substr($value, 8, 3);
$dayStr = substr($value, 5, 2);
$dayStr = preg_replace("/0/", '', $dayStr);
$timeStr = substr($value, 17, 5);
$childrenClass->pubDate = $timeStr.' '.monthTransform($monthStr).$dayStr.'日';
}
// 原文鏈接
$originalLink = $mainEach->getElementsByTagName("link");
forEach($originalLink as $originalLinkEach){
$value = $originalLinkEach->firstChild->nodeValue;
$childrenClass->originalLink = $value;
}
array_push($arrObj, $childrenClass);
}
// 英文月份轉化爲數字
function monthTransform($monthStr){
switch ($monthStr) {
case 'Jan':
return '1月';
break;
case 'Feb':
return '2月';
break;
case 'Mar':
return '3月';
break;
case 'Apr':
return '4月';
break;
case 'May':
return '5月';
break;
case 'Jun':
return '6月';
break;
case 'Jul':
return '7月';
break;
case 'Aug':
return '8月';
break;
case 'Sep':
return '9月';
break;
case 'Oct':
return '10月';
break;
case 'Nov':
return '11月';
break;
case 'Dec':
return '12月';
break;
default:
return '格式錯誤';
break;
}
}
?>
我之前用的是angular, 數據傳輸時, 格式限定非常嚴格(必須是純json字符串, 否則會報錯). 後來又換成了Vue.
vueModule.js
var Promise, Vue, index;
define(function(){return {a: '123'};});
$.post('./php/readXML.php', {param1: '1'}, function(data, textStatus, xhr) {
objEntity = JSON.parse(data); //此時已經取到數據
});
var objEntity = [];
var app = document.getElementById('app');
var news;
require(["jsonp"], function(){
var interval = setInterval(function(){
if (objEntity.description != null) {
news = objEntity.description[0];
console.log(news);
var vueMain = new Vue({
el: '#app',
data: {message: news}
});
clearInterval(interval);
}
}, 50);
});
最重要的是中間那段Vue代碼, 其他的可以不必理會
index.html(顯示數據)
<div id="app">
<div class="item" v-for="(item, index) in items">
<div class="author">
<span>投稿人:{{item.author}}</span>
</div>
<div class="item-up">
<div class="item-up-main">
<a href="javascript:void(0);" v-on:click="newsShow(index)"><b class="title">{{item.title}}<br/></b><br/><span class="shortCut"></span></a>
</div>
<div class="desc"></div>
</div>
<div class="item-down">
<div class="categary">{{item.category}}</div>
<div style="width:1rem;"></div>
<div class="time">{{item.pubDate.substr(0, 5)}}</div>
<div style="width:0.75rem;"></div>
<div class="time">{{item.pubDate.substr(5, 5)}}</div>
<div style="width:3rem;"></div>
</div>
</div>
</div>
最後頁面效果如下圖所示(數據是實時刷新的):
實時數據如下: