做js的ajax應用時,會遇到你需要請求的介面並不在你當前域下,此時就會出現跨域訪問的問題,瀏覽器會禁止你請求這個介面。
此時怎麼訪問這個WebService的介面呢?
一個簡單的辦法就是在本域的伺服器上,增加一個轉寄層,將瀏覽器上過來的請求接收後,通過伺服器將這個請求轉寄到對應的WebService上,然後把返回結果再取回後,送回js的請求頁面。
一般而言這個是解決跨域訪問最安全與最具相容性的辦法。
下面是我寫的一個php指令碼,可以完成這個轉寄過程,僅供參考:
<?php/** * ajax業務處理中的介面轉寄層,解決ajax跨域訪問的問題 * 工作原理:問請求通過本程式做中轉,在本機伺服器層完成與遠程服務介面的互動 * 備忘:使用時 URL_ROOT 這個參數需要根據你的目標介面地址進行修改,本轉寄層之能用於單介面的Web Service介面服務 * 程式支援POST資料與GET數量的同時轉寄; * @version 1.0.0.2 * @author JerryLi lijian@dzs.mobi * @copyright b.dzs.mobi 2012-11-16 * */class interface_relay{/**介面根地址(此處是需要修改的地方)*/const URL_ROOT = 'http://api.air-id.net/InterFace/';/**字元集*/const CHARSET = 'UTF-8';/**GET*/private $msGets = '';/**POST*/private $maGetPostData = array();function __construct(){$this->getPOST();$this->getGET();if($this->msGets != '' || count($this->maGetPostData) > 0){//存在輸入資料if(count($this->msGets) > 0)$sUrl = self::URL_ROOT .'?'. $this->msGets;else$sUrl = self::URL_ROOT;header('Content-Type: text/html; charset='. self::CHARSET);echo $this->getContent($sUrl);}else{header('Content-Type: text/html; charset='. self::CHARSET);echo $this->getContent(self::URL_ROOT);}}function __destruct(){unset($maGetPostData, $msGets);}/** * 載入POST資料 * @return bool * */private function getPOST(){$handle = @fopen('php://input', 'r');$data = '';do{$data = @fread($handle, 1024);if (strlen($data) == 0)break;else$this->maGetPostData[] = $data;}while(true);fclose($handle);unset($data, $handle);return count($this->maGetPostData) >= 1;}/** * 載入GET資料 * @return bool * */private function getGET(){/*取得GET內容*/if (count($_GET) > 0){$aTmp = array();foreach ($_GET as $sKey => $sVal)$aTmp[] = $sKey .'='. urlencode($sVal);$this->msGets = implode('&', $aTmp);return true;}elsereturn false;}/** * 讀取遠程介面返回的內容 * @return string * */private function getContent($sGetUrl){/**/$ch = curl_init();curl_setopt ($ch, CURLOPT_URL, $sGetUrl); //設定GET的URL地址curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);//將結果儲存成字串curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 10);//連線逾時時間scurl_setopt ($ch, CURLOPT_TIMEOUT, 10);//執行逾時時間scurl_setopt ($ch, CURLOPT_DNS_CACHE_TIMEOUT, 1800);//DNS解析緩衝儲存時間半小時curl_setopt($ch, CURLOPT_HEADER,0);//丟迴轉資訊if (count($this->maGetPostData) > 0){//存在POST資料需要提交curl_setopt($ch, CURLOPT_POST, 1); //啟用POST資料curl_setopt($ch, CURLOPT_POSTFIELDS, implode('', $this->maGetPostData));//提交POST資料}$sData = curl_exec($ch);curl_close($ch);unset($ch);return $sData;}}$o = new interface_relay();unset($o);?>