1、怎麼解決伺服器間的跨域問題
第一種
如果您使用的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
2、跨域是指什麼,因為什麼引起的?有哪些解決方案?web前端知識
域(Domain)是Windows網路中獨立運行的單位,域之間相互訪問則需要建立信任關系(即Trust Relation)。信任關系是連接在域與域之間的橋梁。當一個域與其他域建立了信任關系後,2個域之間不但可以按需要相互進行管理,還可以跨網分配文件和列印機等設備資源,使不同的域之間實現網路資源的共享與管理。 有一種簡明的說法來解釋廣域跨域:跨域訪問,簡單來說就是 A 網站的 javascript 代碼試圖訪問 B 網站,包括提交內容和獲取內容。由於安全原因,跨域訪問是被各大瀏覽器所默認禁止的。
解決方案:
1、js向伺服器發送請求,然後讓伺服器去另一個域上獲取數據後返回。(用於你無法控制另一個域) 比如php中利用cUrl。
2、放置跨域文件.
3、用JSONP。雖然不能跨域進行通信,但是可以引入跨域的js文件。
先定義一個函數
當我們要向www.baidu.com/s.php請求數據的時候,我們可以引入某個包含返回信息的js文件。
比如: <script type="text/javascript" src="www.baidu.com/s.php?id=12321" />
js的內容是getData({json:'格式'});返回時輸出 格式是 text/javascript (比如php用header('Content-type:text/javascript');來輸出)
那麼文件載入好後解析js時就會執行這個函數,返回得到的數據就被賦值給了returnData變數
以這樣的方式插入到頁面中:
3、怎麼解決伺服器間的跨域問題
空間在展現每個UWA開放模塊之前都必須請求該模塊的xml源代碼以進行解析,鑒於安全性等問題的考慮。但這些方法都有一定的局限性,再由本域伺服器的代理來請求數據並將響應返回給客戶端。
下面我們將以空間的開放平台為例。要解決該問題,只能讓js向hi域的web伺服器請求xml文件;uwa目錄下,並簡單介紹下spproxy的一些特性服務端的解決方案的基本原理就是;ow/、transmit的分流以及space的spproxy模塊來解
決該跨域問題,如apache和lighttpd的mod_proxy模塊,每個模塊的源代碼文件都是存放在act域下的/。在百度內
部、缺點及下一步的改進計劃,簡單介紹下如何通過apache的mod_proxy,由客戶端將請求發給本域伺服器,space這邊最後開發了一個專門用於處
理跨域請求代理服務的spproxy模塊、transmit分流,而hi域web服務
器則通過一定的代理機制(如mod_proxy,那麼在
用戶空間首頁(hi域)中請求該xml文件時就會存在js跨域問題,用於徹底解決js跨域問題,transmit的分流功能也可以解決部分跨域問題。
最常用的伺服器解決方案就是利用web伺服器本身提供的proxy功能
4、為什麼要跨域以及跨域的作用是什麼
跨域,指的是瀏覽器不能執行其他網站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對JavaScript施加的安全限制。
5、怎麼解決伺服器間的跨域問題
服務端的解決方案的基本原理就是,由客戶端將請求發給本域伺服器,再由本域伺服器的代理來請求數據並將響應返回給客戶端。
最常用的伺服器解決方案就是利用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伺服器請求文件
6、跨域 可以通過伺服器代理進行跨域嗎 這樣js 就可以直接 訪問別人的介面了嗎
給你個例子,controller需要支持跨域的方法:publicMapindex(ServletResponseres){HttpServletResponseresponse=(HttpServletResponse)res;response.addHeader("Access-Control-Allow-Origin","*");response.addHeader("Access-Control-Allow-Methods","POST,GET,PUT,DELETE,OPTIONS");response.addHeader("Access-Control-Allow-Credentials","true");response.addHeader("Access-Control-Allow-Headers","Content-Type,X-Requested-With,token");response.addHeader("Access-Control-Max-Age","600000");//TODO}這樣就支持跨域了,但是這種方式不怎麼安全,"Access-Control-Allow-Origin"後面的*代表支持所有域名。
7、如何讓伺服器支持跨域
要看伺服器類型,如果伺服器是apache
(1)修改http服務的配置文件:C:\wamp\bin\apache\Apache2.4.4\conf\httpd.conf
把LoadMole headers_mole moles/mod_headers.so 前面的注釋刪除.
(2)添加Header set Access-Control-Allow-Origin *
<Directory />
AllowOverride none
Require all granted
Header set Access-Control-Allow-Origin *
</Directory>
(3)重啟http服務
如果是tomcat,比如spring MVC項目
創建一個過濾器,代碼如下:
Java代碼 收藏代碼
package com.web.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import com.common.dict.Constant2;
import oa.service.DictionaryParam;
public class SimpleCORSFilter implements Filter{
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", DictionaryParam.get(Constant2.DICTIONARY_GROUP_GLOBAL_SETTING, "AccessControlAllowOrigin"));
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
}
關鍵代碼:response.setHeader("Access-Control-Allow-Origin", "*");
<filter>
<filter-name>cors</filter-name>
<filter-class>com.web.filter.SimpleCORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
這樣伺服器就支持ajax的跨域訪問了.
8、說明跨域產生的原因是什麼
跨域請求存在的原因:由於瀏覽器的同源策略,即屬於不同域的頁面之間不能相互訪問各自的頁面內容。
跨域的方式
1.前端的方式: possMessage,window.name,document.domain,image.src(得不到數據返回),jsonP(script.src後台不配合得不到數據返回),style.href(得不到數據返回)
一.imge.src,script.src,style.href 不受同源策略的影響可以載入其他域的資源,可以用這個特性,向伺服器發送數據。最常用的就是使用image.src 向伺服器發送前端的錯誤信息。image.src 和style.href 是無法獲取伺服器的數據返回的,script.src 伺服器端配合可以得到數據返回。
二possMessage,window.name,document.domain 是兩個窗口直接相互傳遞數據。
(1)possMessage 是HTML5中新增的,使用限制是 必須獲得窗口的window 引用。IE8+支持,firefox,chrome,safair,opera支持
(2)window.name ,在一個頁面中打開另一個頁面時,window.name 是共享的,所以可以通過window.name 來傳遞數據,window.name的限制大小是2M,這個所有瀏覽器都支持,且沒有什麼限制。
3) document.domain 將兩個頁面的document.domain 設置成相同,document.domain 只能設置成父級域名,既可以訪問,使用限制:這頂級域名必須相同
2.純後端方式: CORS,伺服器代理
CORS 是w3c標準的方式,通過在web伺服器端設置:響應頭Access-Cntrol-Alow-Origin 來指定哪些域可以訪問本域的數據,ie8&9(XDomainRequest),10+,chrom4 ,firefox3.5,safair4,opera12支持這種方式。
伺服器代理,同源策略只存在瀏覽器端,通過伺服器轉發請求可以達到跨域請求的目的,劣勢:增加伺服器的負擔,且訪問速度慢。
3.前後端結合:JsonP
script.src 不受同源策略的限制,所以可以動態的創建script標簽,將要請求數據的域寫在src 中參數中附帶回調的方法,伺服器端返回回調函數的字元串,並帶參數。
9、怎麼解決伺服器間的跨域問題
關於跨域名問題還是問題么,這方面的解決實踐非常多,今天我就舊話重提把我所知道的通過幾個應用場景來分別總結一下(轉帖請註明出處: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
10、前端和後端放在同一個伺服器上是跨域嗎
先了解同源策略吧。指的是,同埠,同域名,同協議。
這三者只要有任意一個不符合,就屬於跨域。