1、跨域是指什麼,因為什麼引起的?有哪些解決方案?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變數
以這樣的方式插入到頁面中:
2、前端和後端放在同一個伺服器上是跨域嗎
先了解同源策略吧。指的是,同埠,同域名,同協議。
這三者只要有任意一個不符合,就屬於跨域。
3、有一個第三方介面,我要用ajax請求,出現跨域。不能修改第三方伺服器,並且只能用post提交有什麼方案
你好,你可以用ajax請求本地的介面,本地介面使用curl方式調用第三方伺服器就沒有問題了。
4、怎麼跨域獲取到json數據呢?伺服器端有什麼要求嗎?
1、通過jQuery的ajax進行跨域,這其實是採用的jsonp的方式來實現的。
jsonp是英文json with padding的縮寫。它允許在伺服器端生成script tags至返回至客戶端,也就是動態生成javascript標簽,通過javascript callback的形式實現數據讀取。
html頁面端示例代碼:
復制代碼 代碼如下:
//首先要引入jquery的js包
jQuery(document).ready(function(){
$.ajax({
type : "get", //jquey是不支持post方式跨域的
async:false,
url : "http://api.taobao.com/apitools/ajax_props.do", //跨域請求的URL
dataType : "jsonp",
//傳遞給請求處理程序,用以獲得jsonp回調函數名的參數名(默認為:callback)
jsonp: "jsoncallback",
//自定義的jsonp回調函數名稱,默認為jQuery自動生成的隨機函數名
jsonpCallback:"success_jsonpCallback",
//成功獲取跨域伺服器上的json數據後,會動態執行這個callback函數
success : function(json){
alert(json);
}
});
});
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、伺服器不支持jsonp格式怎麼跨域訪問
您好,這樣的:
$.ajax({
async:false,
url: '', // 跨域URL
type: 'GET',
dataType: 'jsonp',
jsonp: 'jsoncallback', //默認callback
data: mydata, //請求數據
timeout: 5000,
beforeSend: function(){ //jsonp 方式此方法不被觸發。原因可能是dataType如果指定為jsonp的話,就已經不是ajax事件了
},
success: function (json) { //客戶端jquery預先定義好的callback函數,成功獲取跨域伺服器上的json數據後,會動態執行這個callback函數
if(json.actionErrors.length!=0){
alert(json.actionErrors);
}
},
complete: function(XMLHttpRequest, textStatus){
},
error: function(xhr){
//jsonp 方式此方法不被觸發
//請求出錯處理
alert("請求出錯(請檢查相關度網路狀況.)");
}
});
7、怎麼解決伺服器間的跨域問題
關於跨域名問題還是問題么,這方面的解決實踐非常多,今天我就舊話重提把我所知道的通過幾個應用場景來分別總結一下(轉帖請註明出處: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
8、如何讓伺服器支持跨域
要看伺服器類型,如果伺服器是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的跨域訪問了.
9、怎麼解決伺服器間的跨域問題
通過設置Http Header方式允許跨域名請求
<?php
header("Access-Control-Allow-Origin: http://www.requesting-page.com");
?>
more details
browser(client) side code examples:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
server side code examples:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Server-Side_Access_Control
怎樣配置Apache 伺服器允許跨域名請求
How do we fix cross domain scripting issue ?
The simple solution is to allow the server to which request is being
made to server request to any domain or to a list of domains. The
important thing to remember is that the changes are to be made in the server which is serving the web service.
There are multiple ways to do it
1. You change settings in your apache』s httpd-vhosts.conf file ( I am using Apache 2.2 )
<VirtualHost *:80>
ServerAdmin [email protected]
DocumentRoot 「C:/apache-tomcat-6.0.29/webapps/myApplication」
ServerName skill-guru.com
ErrorLog 「logs/skg1-error.log」
CustomLog 「logs/skg1-access.log」 common
Header set Access-Control-Allow-Origin 「*」
<Directory 「C:/apache-tomcat-6.0.29/webapps/myApplication」>
Options -Indexes FollowSymLinks
AllowOverride AuthConfig FileInfo
Order allow,deny
Allow from all
</Directory>
JkUnmount /*.jsp ajp13
</VirtualHost>
Now after you set the value in apache server and look at the header and would see
HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.0.61
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml
怎樣配置Tomcat 伺服器允許跨域名請求
If you do not plan to use Apache and for some reasons using tomcat or
any other similar web container which supports filter, here is a ready
made solution, Cors
Filter
This gives you a servlet filter which is compatible with any Java Servlet 2.5+ web container.
Installation is very simple. Add the jar to your libraries
In you web.xml
add this line
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CORS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>