『壹』 PHP如何實現跨域
因工作需要,客戶端軟體的一些界面用HTML+CSS+Javascript實現,這些文件放在客戶端本地,以本地文件形式載入,但是有些情況下,需要連接伺服器取得一些信息,如果不做任何處理,則請求失敗,返回的信息如下:
No
'Access-Control-Allow-Origin'
header
is
present
on
the
requested
resource.
Origin
'null'
is
therefore
not
allowed
access.
這是因為瀏覽器跨域策略起作用,阻止了跨域的請求。看看HTTP請求過程就知道。第一次請求後端時候,瀏覽器意識到是訪問一個跨與資源,沒有直接發送GET請求獲取數據,而是發送了一個OPTIONS請求詢問是否可以訪問該資源。我們稱之為Preflight請求,默認因為同源策略的存在,該請求返回的Header中沒有'Access-Control-Allow-Origin'屬性,所以訪問失敗。
如果要實現跨域,關鍵在於伺服器,客戶端的代碼按照正常的方式編寫即可。對於伺服器,只需要在收到OPTIONS請求的地方,返回的頭信息中增加該屬性即可,代碼如下:
header("Access-Control-Allow-Origin:
*");
注意,一定要在所有信息輸出到客戶端之前設置。
以上所述是小編給大家介紹的PHP如何實現跨域的相關內容,希望對大家有所幫助!
『貳』 如何解決跨域問題
關於跨域名問題還是問題么,這方面的解決實踐非常多,今天我就舊話重提把我所知道的通過幾個應用場景來分別總結一下(轉帖請註明出處:http://blog.csdn.net/lenel)
先說明一點:我說的某某域名在您的控制下的意思是這個域名下的網頁由您來負責開發內部的JavaScript
場景一:將bbs.xxx.com的頁面用iframe嵌入到www.xxx.com的中,如何在iframe內外使用js通信(轉帖請註明出處:http://blog.csdn.net/lenel)
一級域名都是xxx.com 這個域名一定是在您的控制下,所以你只要在兩個頁面中同時升級域名即可
在父窗口和iframe內部分別加上js語句:document.domain="xxx.com";
之後2個頁面就等於在同一域名下,通過window.parent oIframe.contentDocument就可以相互訪問,進行無障礙的JS通信
在新浪、淘寶等很多頁面都能找到這樣的語句。不過document.domain不可以隨便指定,只能向上升級,從bbs.xxx.com升級到yyy.com肯定會出錯
場景二:將www.yyy.com的頁面用iframe嵌入到www.xxx.com的中,兩個域名都在您的控制下,如何在iframe內外進行一定的數據交流(轉帖請註明出處:http://blog.csdn.net/lenel)
你可以通過相互改變hash值的方式來進行一些數據的通信
這里的實現基於如下技術要點:
1、父窗口通過改變子窗口的src中的hash值把一部分信息傳入,如果src只有hash部分改變,那麼子窗口是不會重新載入的。
2、
子窗口可以重寫父窗口的location.href,但是注意這里子窗口無法讀取而只能重寫location.href所以要求前提是您控制兩個域名,知
道當前父窗口的location.href是什麼並寫在子窗口內,這樣通過parent.location.href =
"已知的父窗口的href"+"#"+hash。這樣父窗口只有hash改變也不會重載。
3、上面兩步分別做到了兩個窗口之間的無刷新數據通知,
那麼下面的來說如何感知數據變化。標准中沒有相關規定,所以當前的任意瀏覽器遇到location.hash變化都不會觸發任何javaScript事
件,也就是說您要自己寫監聽函數來監視loaction.hash的值的變化。做法是通過setTimeout或者setInterval來寫一個監聽函
數每20-100ms查看一下hash是否變化,如果變化了驅動js根據新的數據做想做的事情。
這種實現的一些分析:
1、信息通道是雙向的,當然會兼容單向,如果只是父窗口向子窗口通知數據,只需要子窗口寫hash監聽,反之亦然。
2、局限性也是頗大,因為這種通信的前提是雙方知道對方的location.href。如果父窗口帶有動態的location.search也就是查詢參數,那麼子窗口的處理上就比較困難,需要把父窗口的location.search作為傳遞信息的一部分告知子窗口。
3、另外的困擾會有瀏覽器帶給你,IE之外的瀏覽器遇到hash的改變會記錄歷史,這樣你在處理前進後退的時候會非常頭疼
場景三:將www.yyy.com的頁面用iframe嵌入到www.xxx.com的中,只有被嵌入的yyy.com在您的控制下,如何在iframe內外進行一定的交流
真實場景:google adsence的一個需求,你希望google發現您的頁面不能匹配出相關性非常好的按點擊付費廣告時,你希望google的廣告iframe能夠隱藏。
google的廣告iframe在google域下顯然不能把自己隱藏掉,那麼怎麼辦呢?
1、google會提供給你一個html頁面
2、您將這個頁面放置在您的域名下,並告訴google它的位置
3、當google發現沒有很好的廣告時,會將子窗口的loaction重定向到您的那個頁面下,這樣您的頁面因為同域名就可以訪問父頁面來隱藏自己了
是不是很巧的方法?
場景四:您是內容發布商,如何改造介面,讓其他域名下的頁面可以從瀏覽器端出發獲得您的數據
我們知道ajax的xmlHttpRequest()說到底是一個無刷新請求伺服器數據的輔助工具,但是xmlHttpRequest並不能跨域名請求數據,在某些情況下成了極大的限制。
但是我們如果通過其他方式完成無刷新請求數據不也可以么,我們用Dom方法操作動態JS腳本請求來做這件事。
//創建一個腳本節點
var oScript = document.createElement('script');
//指定腳本src src可以指向任意域名
//注意src不再指向靜態js,而是帶著查詢參數指向一個動態腳本廣播服務。
oScript.src = "http://yyy.com/query.php?"+yourQueryString;
//如果指定了charset 同時還可以解決xmlHttpRequest另一大困擾 亂碼問題
//oScript.charset = "utf-8";
//通過Dom操作把這個新的節點加入到文檔當中
document.getElementsByTagName("head")[0].appendChild(oScript);
這樣只要query.php的輸出是可執行的javaScript腳本,比如:djsCallBack({jsondata});
當他從伺服器返回後就會自動執行,你可以方便的用json方式來做數據傳遞了。
要注意,您的腳本請求最好帶上時間戳,避免瀏覽器緩存造成取回數據實時性下降。
如果您是數據提供者,您可以要求數據索取者在查詢參數中提供回調函數名,比如query.php?callback=myDataHandler&key=...?
這樣您就可以根據參數來提供給他myDataHandler({jsondata}),這樣不同的數據索取者都會得到自定義的正確的非同步回調。
進一步發展,可以做一個統一的從xml到動態json的數據轉化伺服器,脫離數據的實際意義,針對任何xml介面都可以作為轉化後提供給客戶端直接訪問。
這樣就不用針對單獨xml數據服務,為了跨域名而做各自的後台數據抓取轉化服務。
用動態腳本傳數據功能非常強大,去年我最先在YAHOO的站點上看到這樣的應用,讓人眼前一亮。
總結總結:
第一種場景,相應的處理辦法有這非常好的效果,可以說完全解決了問題。
第二種場景,相應的處理辦法具有一定的跨域數據交流功效,具有相當大的局限,並不適合在復雜業務流程中應用,實際上我也確實也沒看到過基於此的大規模應用。
第三種場景,相應的處理辦法比較巧妙,雖然redirect之後就不幹你什麼事了,但如果你是google一樣面向眾多域名的內容提供商,也是個不錯的解決思路。
第四種場景,相應的處理辦法非常強大,對比Ajax可以看到,跨域名沒問題,無刷新沒問題,本身又是非同步的,JSON比xml快的多,同時解決亂碼問題,只是請求都是Get方式的,不能做Post方式的請求。多一種武器自然可以從容選擇了
『叄』 php什麼是跨域,怎麼解決跨域問題
伺服器端PHP跨域一般沒有限制,不像瀏覽器端有same origin policy。
把伺服器B中的代碼封裝一下,確定好輸入和輸出,比如輸入是一個HTTP Request,參數POST過去;輸出是從HTTP Response返回一段XML。之後在伺服器A的代碼中做一個對伺服器B的HTTP請求並處理返回的XML就好了
『肆』 跨域是指什麼,因為什麼引起的有哪些解決方案web前端知識
廣義跨域就是指跨域訪問,簡單來說就是 A 網站的 javascript 代碼試圖訪問 B 網站,包括提交內容和獲取內容。由於安全原因,跨域訪問是被各大瀏覽器所默認禁止的。
當一個域與其他域建立了信任關系後,2個域之間不但可以按需要相互進行管理,還可以跨網分配文件和列印機等設備資源,使不同的域之間實現網路資源的共享與管理。這就形成了「跨域」。
『伍』 跨域問題解決方法
跨域?他是瀏覽器的 同源策略 造成的,是瀏覽器對javascript施加的安全限制。所謂同源是指:域名、協議、埠均相同。
解決
原理:利用標簽具有可跨域的特性,可實現跨域訪問介面,需要後端的支持。
伺服器在收到請求後,解析參數,計算返還數據,輸出messagetow(data)字元串。
缺點:只能發送get請求,無法訪問伺服器的響應文本(單向請求),即只能獲取數據不能改數據。
通過ajax請求不同域的實現,底層不是靠XmlHttpRequest而是script,所以不要被這個方法給迷惑了。
在ajax請求中類型如果是type是get post,其實內部都只會用get,因為其跨域的原理就是用的動態載入script的src,所以我們只能把參數通過url的方式傳遞
其實jquery內部會轉化成
http://192.168.31.137/train/test/jsonpthree?callback=messagetow
然後動態載入http://192.168.1.114/yii/demos/test.php?backfunc=jQuery2030038573939353227615_1402643146875&action=aaron">
http://192.168.1.114/yii/demos/test.php?backfunc=jQuery2030038573939353227615_1402643146875&action=aaron"><script type="text/javascript" src=" http://192.168.31.137/train/test/jsonpthree?callback=messagetow "></script>
http://192.168.1.114/yii/demos/test.php?backfunc=jQuery2030038573939353227615_1402643146875&action=aaron">
http://192.168.1.114/yii/demos/test.php?backfunc=jQuery2030038573939353227615_1402643146875&action=aaron">
Cross-Origin Resource Sharing(CORS)跨域資源共享是一份瀏覽器技術的規范,提供了 Web 服務從不同域傳來沙盒腳本的方法,以避開瀏覽器的同源策略,確保安全的跨域數據傳輸。現代瀏覽器使用CORS在API容器如XMLHttpRequest來減少HTTP請求的風險來源。與 JSONP 不同,CORS 除了 GET 要求方法以外也支持其他的 HTTP 要求。伺服器一般需要增加如下響應頭的一種或幾種:
跨域請求默認不會攜帶Cookie信息,如果需要攜帶,請配置下述參數:
window.name通過在iframe(一般動態創建i)中載入跨域HTML文件來起作用。然後,HTML文件將傳遞給請求者的字元串內容賦值給window.name。然後,請求者可以檢索window.name值作為響應。
iframe標簽的跨域能力;
window.name屬性值在文檔刷新後依舊存在的能力(且最大允許2M左右)。
每個iframe都有包裹它的window,而這個window是top window的子窗口。 contentWindow 屬性返回<iframe>元素的Window對象。你可以使用這個Window對象來訪問iframe的文檔及其內部DOM。
HTML5新特性,可以用來向其他所有的 window 對象發送消息。需要注意的是我們必須要保證所有的腳本執行完才發送 MessageEvent,如果在函數執行的過程中調用了它,就會讓後面的函數超時無法執行。
前提條件:這兩個域名必須屬於同一個基礎域名!而且所用的協議,埠都要一致,否則無法利用document.domain進行跨域,所以只能跨子域
在 根域 范圍內,允許把domain屬性的值設置為它的上一級域。例如,在」aaa.xxx.com」域內,可以把domain設置為 「xxx.com」 但不能設置為 「xxx.org」 或者」com」。
現在存在兩個域名aaa.xxx.com和bbb.xxx.com。在aaa下嵌入bbb的頁面,由於其document.name不一致,無法在aaa下操作bbb的js。可以在aaa和bbb下通過js將document.name = 'xxx.com';設置一致,來達到互相訪問的作用。
WebSocket protocol 是HTML5一種新的協議。它實現了瀏覽器與伺服器全雙工通信,同時允許跨域通訊,是server push技術的一種很棒的實現。相關文章,請查看: WebSocket 、 WebSocket-SockJS
**需要注意:**WebSocket對象不支持DOM 2級事件偵聽器,必須使用DOM 0級語法分別定義各個事件。
同源策略是針對瀏覽器端進行的限制,可以通過伺服器端來解決該問題,例如nginx
DomainA客戶端(瀏覽器) ==> DomainA伺服器 ==> DomainB伺服器 ==> DomainA客戶端(瀏覽器)
『陸』 PHP 如何實現不同網站登錄跨域的問題
可以用sso單點登錄解決這個問題,本質是不同的域名能同時記錄同一個cookie
很久之前做過這個功能,有點忘了,大概的步驟:
例如你在test1.com登錄成功後,會給一個應用中心發請求,這個應用中心保存著所有的sso登錄的設置cookie的url,每個應用組裝成一個script標簽返回給你
你接收到這些script標簽後,讓這些標簽執行就可以了,例如B站點的響應中就會有setCookie這個響應頭,這樣B站點的登錄cookie就在你的瀏覽器上保存了
每個站點在你的瀏覽器上都有cookie了,自然就處於登錄狀態了
很久之前做過的,大體思想是這些
『柒』 php跨域問題(cors)
ajax跨域需要用jsonp方式的,
php跨域 這個你可以用curl,
至於你那個 自己用debug看下吧!
『捌』 thinkphp6解決跨域
寫一個前後端分離的項目 解決thinkphp6跨域問題
在這里可以使用tp6的前置中間件
首先開啟中間件的文件配置
然後創建一個中間件文件
最後配置
『玖』 PHP跨域上傳的幾種方法
方法一:
文件夾:/home/web/attachments
虛擬二級目錄到/home/web/zxsv/下(支持同區域網的伺服器)
這樣多個子域名進行上傳的設計時,只需要attachments目錄映射為相關的域名的二級目錄,這樣就可實現多個子域名共享一個附件伺服器了,這種方法最好是用區域網中的附件伺服器,這樣流量是分開的,當然訪問附件的域名是apache,ngixn,IIS等的虛擬二級目錄就不說了,好處是現有程序不做任何修改,唯一壞處就是兩台伺服器必須在一個區域網中,當然你用單台也就沒這個問題了
方法二:FTP同步更新
PHP是支持FTP的,給個FTP類裡面(不是我寫的,只是加了個建立多級目錄),自己看著辦吧,上傳後調用FTP類,同步到FTP伺服器中,好處是現有程序只需要在上傳那段加上FTP上傳就行了,壞處就是一定要支持FTP
<?php
$ftp=new Ftp;
//print_r($ftp->nlist(」"));
$ftp->makedir(」3″);
//$ftp->put(」comment.php」,」1.txt」);
$ftp->bye();
//R FTP 處理;
class ftp {
var $ftpUrl = 『www.zxsv.com』;
var $ftpUser = 『zxsv』;
var $ftpPass = 『111111′;
var $ftpDir = 『/zxsv/』;
var $ftpR = 」; //R ftp資源;
var $status = 」;
//R 1:成功;2:無法連接ftp;3:用戶錯誤;
function ftp() {
if ($this->ftpR = ftp_connect($this->ftpUrl, 21)) {
if (ftp_login($this->ftpR, $this->ftpUser, $this->ftpPass)) {
if (!empty($this->ftpDir)) {
ftp_chdir($this->ftpR, $this->ftpDir);
}
ftp_pasv($this->ftpR, true);//R 啟用被動模式;
$status = 1;
} else {
$status = 3;
}
} else {
$status = 2;
}
}
//R 切換目錄;
function cd($dir) {
return ftp_chdir($this->ftpR, $dir);
}
//建立目錄
function mkdir($dir){
return ftp_mkdir($this->ftpR, $dir);
}
function makedir($dir) {
if(!$dir) return 0;
$dir = str_replace( 「\\」, 「/」, $dir );
$mdir = 「」;
foreach(explode( 「/」, $dir ) as $val ) {
$mdir .= $val.」/」;
if( $val == 「..」 || $val == 「.」 ) continue;
if(!@mkdir($mdir)){
echo 「創建目錄 [".$mdir."]失敗.」;
//exit;
}
}
return true;
}
//刪除目錄
function rmdir($dir){
return ftp_rmdir($this->ftpR, $dir);
}
//R 返回當前路勁;
function pwd() {
return ftp_pwd($this->ftpR);
}
//R 上傳文件;
function put($localFile, $remoteFile = 」) {
if ($remoteFile == 」) {
$remoteFile = end(explode(』/', $localFile));
}
$res = ftp_nb_put($this->ftpR, $remoteFile, $localFile, FTP_BINARY);
print_r($res);
while ($res == FTP_MOREDATA) {
$res = ftp_nb_continue($this->ftpR);
}
if ($res == FTP_FINISHED) {
return true;
} elseif ($res == FTP_FAILED) {
return false;
}
}
//R 下載文件;
function get($remoteFile, $localFile = 」) {
if ($localFile == 」) {
$localFile = end(explode(』/', $remoteFile));
}
if (ftp_get($this->ftpR, $localFile, $remoteFile, FTP_BINARY)) {
$flag = true;
} else {
$flag = false;
}
return $flag;
}
//R 文件大小;
function size($file) {
return ftp_size($this->ftpR, $file);
}
//R 文件是否存在;
function isFile($file) {
if ($this->size($file) >= 0) {
return true;
} else {
return false;
}
}
//R 文件時間
function fileTime($file) {
return ftp_mdtm($this->ftpR, $file);
}
//R 刪除文件;
function unlink($file) {
return ftp_delete($this->ftpR, $file);
}
function nlist($dir = 『/service/resource/』) {
return ftp_nlist($this->ftpR, $dir);
}
//R 關閉連接;
function bye() {
return ftp_close($this->ftpR);
}
}
?>