跨域問題怎麼解決?
如何解決跨域問題
由 於此前很少寫前端的代碼(哈哈,不合格的程序員啊),最近項目中用到json作為系統間交互的手段,自然就伴隨著眾多ajax請求,隨之而來的就是要解決 ajax的跨域問題。本篇將講述一個小白從遇到跨域不知道是跨域問題,到知道是跨域問題不知道如何解決,再到解決跨域問題,最後找到兩種方法解決ajax 跨域問題的全過程。
不知是跨域問題
起 因是這樣的,為了複用,減少重複開發,單獨開發了一個用戶權限管理系統,共其他系統獲取認證與授權信息,暫且稱之為A系統;調用A系統以B為例。在B系統 中用ajax調用A系統系統的接口(數據格式為json),當時特別困惑,在A系統中訪問相應的url可正常回返json數據,但是在B系統中使用 ajax請求同樣的url則一點兒反應都沒有,好像什麼都沒有發生一樣。這樣反反覆覆改來改去好久都沒能解決,於是求救同事,提醒可能是ajax跨域問 題,於是就將這個問題當做跨域問題來解決了。
知跨域而不知如何解決
知道問題的確切原因,剩下的就是找到解決問題的方法了。google了好久,再次在同事的指點下知道jQuery的ajax有jsonp這樣的屬性可以用來解決跨域的問題。
找到一種解決方式
現在也知道了怎樣來解決跨域問題,餘下的就是實現的細節了。實現的過程中錯誤還是避免不了的。由於不瞭解json和jsonp兩種格式的區別,也犯了錯誤,google了好久才解決。
首先來看看在頁面中如何使用jQuery的ajax解決跨域問題的簡單版:
複製代碼
$(document).ready(function(){
var url='localhost:8080/...upById"
+"?id=1&callback=?';
$.ajax({
url:url,
dataType:'jsonp',
processData: false,
type:'get',
success:function(data){
alert(data.name);
},
error:function(XMLHttpRequest, textStatus, errorThrown) {
alert(XMLHttpRequest.status);
alert(XMLHttpRequest.readyState);
alert(textStatus);
}});
});
複製代碼
這樣寫是完全沒有問題的,起先error的處理函數中僅僅是alert(“error”),為了進一步弄清楚是什麼原因造成了錯誤,故將處理函數變 為上面的實現方式。最後一行alert使用為;parsererror。百思不得其解,繼續google,最終還是在萬能的stackoverflow找 到了答案,鏈接在這裡。原因是jsonp的格式與json格式有著細微的差別,所以在server端的代碼上稍稍有所不同。
比較一下json與jsonp格式的區別:
json格式:
{
"message&q......
怎麼解決服務器間的跨域問題
服務端的解決方案的基本原理就是,由客戶端將請求發給本域服務器,再由本域服務器的代理來請求數據並將響應返回給客戶端。
最常用的服務器解決方案就是利用web服務器本身提供的proxy功能,如apache和lighttpd的mod_proxy模塊。在百度內 部,transmit的分流功能也可以解決部分跨域問題。但這些方法都有一定的侷限性,鑑於安全性等問題的考慮,space這邊最後開發了一個專門用於處
理跨域請求代理服務的spproxy模塊,用於徹底解決js跨域問題。
下面我們將以空間的開放平臺為例,簡單介紹下如何通過apache的mod_proxy、transmit的分流以及space的spproxy模塊來解
決該跨域問題,並簡單介紹下spproxy的一些特性、缺點及下一步的改進計劃。
空間在展現每個UWA開放模塊之前都必須請求該模塊的xml源代碼以進行解析,每個模塊的源代碼文件都是存放在act域下的/ow/uwa目錄下,那麼在
用戶空間首頁(hi域)中請求該xml文件時就會存在js跨域問題。要解決該問題,只能讓js向hi域的web服務器請求xml文件,而hi域web服務
器則通過一定的代理機制(如mod_proxy、transmit分流、spproxy)向act域的web服務器請求文件
如何解決javascript的跨域問題
一般是用iframe設置
document.domain = 'a.com';var ifr = document.createElement('iframe');ifr.src = 'a.com/index.html';ifr.style.display = 'none';document.body.appendChild(ifr);ifr.onload = function(){ var doc = ifr.contentDocument || ifr.contentWindow.document; console.log(doc.documentElement.innetHTML);};然後HTML5新特性有 ,postMessage
function Init () { if (window.addEventListener) {// all browsers except IE before version 9 window.addEventListener ("message", OnMessage, false); } else { if (window.attachEvent) {// IE before version 9 window.attachEvent("onmessage", OnMessage); } } } function GetState () { var frame = document.getElementById ("myFrame"); var message = "getstate";//參數if (frame.contentWindow.postMessage) { //傳遞的參數,後面是傳遞的你的跨域域名frame.contentWindow.postMessage (message, "*"); } } function OnMessage (event) { console.log(event.data);} document.body.onload=function(){Init();GetState();};
如何解決跨域問題
VPN或者域名
如何解決跨域問題
關於跨域名問題還是問題麼,這方面的解決實踐非常多,今天我就舊話重提把我所知道的通過幾個應用場景來分別總結一下(轉帖請註明出處:blog.csdn.net/lenel)
先說明一點:我說的某某域名在您的控制下的意思是這個域名下的網頁由您來負責開發內部的JavaScript
場景一:將bbs.xxx.com的頁面用iframe嵌入到www.xxx.com的中,如何在iframe內外使用js通信(轉帖請註明出處: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內外進行一定的數據交流(轉帖請註明出處: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事
......
如何配置解決跨域的問題
解決ajax跨域問題方法1:
在服務器端直接設置header內容:Access-Control-Allow-Origin:*
或者
Access-Control-Allow-Origin:允許訪問的url
這樣就可以直接請求到任何網站或者允許訪問的url
php程序這樣寫:
header('Access-Control-Allow-Origin:*');
或者
header('Access-Control-Allow-Origin:允許訪問的url ');
方法2:
在Nginx設置”頭信息“直接添加Access-Control-Allow-Origin:*的信息。
怎麼解決服務器間的跨域問題
關於跨域名問題還是問題麼,這方面的解決實踐非常多,今天我就舊話重提把我所知道的通過幾個應用場景來分別總結一下(轉帖請註明出處:blog.csdn.net/lenel)
先說明一點:我說的某某域名在您的控制下的意思是這個域名下的網頁由您來負責開發內部的JavaScript
場景一:將bbs.xxx.com的頁面用iframe嵌入到www.xxx.com的中,如何在iframe內外使用js通信(轉帖請註明出處: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內外進行一定的數據交流(轉帖請註明出處:blog.csdn.net/lenel)
你可以通過相互改變hash值的方式來進行一些數據的通信
這裡的實現基於如下技術要點:
1、父窗口通過改變子窗口的src中的hash值把一部分信息傳入,如果src只有hash部分改變,那麼子窗口是不會重新載入的。
2、子窗口可以重寫父窗口的location.href,但是注意這裡子窗口無法讀取而只能重寫location.href所以要求前提是您控制兩個域
名,知道當前父窗口的location.href是什麼並寫在子窗口內,這樣通過parent.location.href =
"已知的父窗口的href" "#" hash。這樣父窗口只有hash改變也不會重載。
3、上面兩步分別做到了兩個窗口之間的無刷新數據通知,那麼下面的來說如何感知數據變化。標準中沒有相關規定,所以當前的任意瀏覽器遇到
loca......
如何解決跨域問題
關於跨域名問題還是問題麼,這方面的解決實踐非常多,今天我就舊話重提把我所知道的通過幾個應用場景來分別總結一下(轉帖請註明出處:blog.csdn.net/lenel)
先說明一點:我說的某某域名在您的控制下的意思是這個域名下的網頁由您來負責開發內部的JavaScript
場景一:將bbs.xxx.com的頁面用iframe嵌入到www.xxx.com的中,如何在iframe內外使用js通信(轉帖請註明出處: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內外進行一定的數據交流(轉帖請註明出處: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變化都不......
如何解決跨域問題
特別注意兩點:
第一,如果是協議和端口造成的跨域問題“前臺”是無能為力的,
第二:在跨域問題上,域僅僅是通過“URL的首部”來識別而不會去嘗試判斷相同的ip地址對應著兩個域或兩個域是否在同一個ip上。
“URL的首部”指window.location.protocol +window.location.host,也可以理解為“Domains, protocols and ports must match”。
2. 前端解決跨域問題
1> document.domain + iframe (只有在主域相同的時候才能使用該方法)
1) 在www.a.com/a.html中:
複製代碼
document.domain = 'a.com';
var ifr = document.createElement('iframe');
ifr.src = 'www.script.a.com/b.html';
ifr.display = none;
document.body.appendChild(ifr);
ifr.onload = function(){
var doc = ifr.contentDocument || ifr.contentWindow.document;
//在這裡操作doc,也就是b.html
ifr.onload = null;
};
複製代碼
2) 在www.script.a.com/b.html中:
document.domain = 'a.com';
2> 動態創建script
這個沒什麼好說的,因為script標籤不受同源策略的限制。
複製代碼
function loadScript(url, func) {
var head = document.head || document.getElementByTagName('head')[0];
var script = document.createElement('script');
script.src = url;
script.onload = script.onreadystatechange = function(){
if(!this.readyState || this.readyState=='loaded' || this.readyState=='complete'){
func();
script.onload = script.onreadystatechange = null;
}
};
head.insertBefore(script......
怎麼解決服務器間的跨域問題
第一種
如果您使用的mvc框架是spring4.2以上的話,一個@CrossOrigin就可以搞定。將@CrossOrigin加到Controller上,那麼這個Controller所有的請求都是支持跨域的,代碼如下:
@Controller
@CrossOrigin
public class GreetingController {123123
將@CrossOrigin加到請求方法上,那麼這個請求是支持跨域的,代碼如下
@CrossOrigin
@RequestMapping("/greeting")
public @ResponseBody Greeting greeting(@RequestParam(required=false, defaultValue="World") String name) {123