⑴ 怎麼解決跨域問題
1、 通過jsonp跨域
JSONP(JSON with Padding:填充式JSON),應用JSON的一種新方法,
JSON、JSONP的區別:
1、JSON返回的是一串數據、JSONP返回的是腳本代碼(包含一個函數調用)
2、JSONP 只支持get請求、不支持post請求
(類似往頁面添加一個script標簽,通過src屬性去觸發對指定地址的請求,故只能是Get請求)
2、代理:
www..com/index.html需要調用www.sina.com/server.php,可以寫一個介面www..com/server.php,由這個介面在後端去調用www.sina.com/server.php並拿到返回值,然後再返回給index.html
3、PHP端修改header
header(『Access-Control-Allow-Origin:*』);//允許所有來源訪問
header(『Access-Control-Allow-Method:POST,GET』);//允許訪問的方式
4、document.domain
跨域分為兩種,一種xhr不能訪問不同源的文檔,另一種是不同window之間不能進行交互操作;
document.domain主要是解決第二種情況,且只能適用於主域相同子域不同的情況;
document.domain的設置是有限制的,我們只能把document.domain設置成自身或更高一級的父域,且主域必須相同。例如:a.b.example.com中某個文檔的document.domain可以設成a.b.example.com、b.example.com 、example.com中的任意一個,但是不可以設成c.a.b.example.com,因為這是當前域的子域,也不可以設成.com,因為主域已經不相同了。
兼容性:所有瀏覽器都支持;
優點:
可以實現不同window之間的相互訪問和操作;
缺點:
只適用於父子window之間的通信,不能用於xhr;
只能在主域相同且子域不同的情況下使用;
使用方式:
不同的框架之間是可以獲取window對象的,但卻無法獲取相應的屬性和方法。比如,有一個頁面,它的地址是http://www.example.com/a.html , 在這個頁面裡面有一個iframe,它的src是http://example.com/b.html, 很顯然,這個頁面與它裡面的iframe框架是不同域的,所以我們是無法通過在頁面中書寫js代碼來獲取iframe中的東西的:
<script type="text/javascript">
function test(){
var iframe = document.getElementById('ifame');
var win = document.contentWindow;//可以獲取到iframe里的window對象,但該window對象的屬性和方法幾乎是不可用的
var doc = win.document;//這里獲取不到iframe里的document對象
var name = win.name;//這里同樣獲取不到window對象的name屬性
}
</script>
<iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>
這個時候,document.domain就可以派上用場了,我們只要把http://www.example.com/a.html 和 http://example.com/b.html這兩個頁面的document.domain都設成相同的域名就可以了。
1.在頁面 http://www.example.com/a.html 中設置document.domain:
<iframe id = "iframe" src="http://example.com/b.html" onload = "test()"></iframe>
<script type="text/javascript">
document.domain = 'example.com';//設置成主域
function test(){
alert(document.getElementById('iframe').contentWindow);//contentWindow 可取得子窗口的 window 對象
}
</script>
2.在頁面 http://example.com/b.html 中也設置document.domain:
<script type="text/javascript">
document.domain = 'example.com';//在iframe載入這個頁面也設置document.domain,使之與主頁面的document.domain相同
</script>
5、window.name
關鍵點:window.name在頁面的生命周期里共享一個window.name;
兼容性:所有瀏覽器都支持;
優點:
最簡單的利用了瀏覽器的特性來做到不同域之間的數據傳遞;
不需要前端和後端的特殊配製;
缺點:
大小限制:window.name最大size是2M左右,不同瀏覽器中會有不同約定;
安全性:當前頁面所有window都可以修改,很不安全;
數據類型:傳遞數據只能限於字元串,如果是對象或者其他會自動被轉化為字元串,如下;
這里寫圖片描述
使用方式:修改window.name的值即可;
6、postMessage
關鍵點:
postMessage是h5引入的一個新概念,現在也在進一步的推廣和發展中,他進行了一系列的封裝,我們可以通過window.postMessage的方式進行使用,並可以監聽其發送的消息;
兼容性:移動端可以放心用,但是pc端需要做降級處理
優點
不需要後端介入就可以做到跨域,一個函數外加兩個參數(請求url,發送數據)就可以搞定;
移動端兼容性好;
缺點
無法做到一對一的傳遞方式:監聽中需要做很多消息的識別,由於postMessage發出的消息對於同一個頁面的不同功能相當於一個廣播的過程,該頁面的所有onmessage都會收到,所以需要做消息的判斷;
安全性問題:三方可以通過截獲,注入html或者腳本的形式監聽到消息,從而能夠做到篡改的效果,所以在postMessage和onmessage中一定要做好這方面的限制;
發送的數據會通過結構化克隆演算法進行序列化,所以只有滿足該演算法要求的參數才能夠被解析,否則會報錯,如function就不能當作參數進行傳遞;
使用方式:通信的函數,sendMessage負責發送消息,bindEvent負責消息的監聽並處理,可以通過代碼來做一個大致了解;
Storage.prototype.sendMessage_ = function(type, params, fn) {
if (this.topWindow) {
this.handleCookie_(type, params, fn);
return;
}
var eventId = this.addToQueue_(fn, type);
var storageIframe = document.getElementById('mip-storage-iframe');
var element = document.createElement("a");
element.href = this.origin;
var origin = element.href.slice(0, element.href.indexOf(element.pathname) + 1);
storageIframe.contentWindow.postMessage({
type: type,
params: params,
eventId: eventId
}, origin);
}
Storage.prototype.bindEvent_ = function() {
window.onmessage = function (res) {
// 判斷消息來源
if (window == res.source.window.parent &&
res.data.type === this.messageType.RES &&
window.location.href.match(res.origin.host).length > 0) {
var fn = this.eventQueue[res.data.eventId];
fn && fn();
delete this.eventQueue[res.data.eventId];
// reset id
var isEmpty = true;
for (var t in this.eventQueue) {
isEmpty = false;
}
if (isEmpty) {
this.id = 0;
}
}
}.bind(this);
}
什麼是跨域?
跨域,指的是瀏覽器不能執行其他網站的腳本。它是由瀏覽器的同源策略造成的,是瀏覽器對JavaScript施加的安全限制
解決辦法:
1、JSONP:
使用方式就不贅述了,但是要注意JSONP只支持GET請求,不支持POST請求。
2、代理:
例如www.123.com/index.html需要調用www.456.com/server.php,可以寫一個介面www.123.com/server.php,由這個介面在後端去調用www.456.com/server.php並拿到返回值,然後再返回給index.html,這就是一個代理的模式。相當於繞過了瀏覽器端,自然就不存在跨域問題。
3、PHP端修改header(XHR2方式)
在php介面腳本中加入以下兩句即可:
header('Access-Control-Allow-Origin:*');//允許所有來源訪問
header('Access-Control-Allow-Method:POST,GET');//允許訪問的方式
⑶ 前端工程師網站跨域問題怎麼解決
1).margin-top,margin-bottom不能正常顯示時
一.有時會遇到外層中的子層使用margin-top不管用的情況;這里我們需要在子層的前後加上一個
div{height:0;overflow:hidden;}
例
CSS樣式表中:
#box {background-color:#eee;}
#box p {margin-top: 20px;margin-bottom: 20px;text-align:center;}
解決方法:在P標簽前後各加2個空的div:<divstyle="height:0;overflow:hidden"></div>
二.網頁中頭部,中部,底部的居底部有時給個margin-bottom:10px;不管用也是要給個清除屬性的.clear{clear:both;font-size:0;line-height:0;}在底部<div id="footer"></div>下加個<div></div>
2).div層中高度自適應問題
網頁前端科技人員在設計網頁時不可能知道客戶在要他們自己的網站內容頁里加多少文字或圖片內容
這時我們就不能規定div層的高度,為此應寫成min-height:200px;height:auto!important;height:
200px;overflow:visible;這樣ie7,ff,ie6瀏覽器的高度自適應問題就解決了,這些在
網站中用到最多了。
3).div層中子層的居底部對齊問題
div中的定位問題有很多也很麻煩,但弄懂了就OK了,在一個大的div層中如何讓子層的內容居底部
對齊就涉及到了position定位問題;
例
div層#box{position:relative;border:1px solidred;width:600px;hegiht:400px;}
div子層#box .wrap{position:absolute;bottom:0;border:1px dashedblue;width:200px;height:
100px},最近寫的網站中就用到了
4).div層中清除clear屬性的一小部分應用
在div中一個大的層裡面有很多子層,若是加上邊框在ie7、ie6中或許會正常顯示,但是在ff中可能
只會成一條線了,此時在最外層的後面加上<div style="clear:both"></div>或者設 .wrapfix:after{
content: ".";
display: block;
height: 0;
clear: both;
visibility: hidden;
}後在每個浮動外框調用wrapfix;學生書網里用到最多了。
5).解決IE8下div移位、錯位等兼容性問題
在<head>標簽後面的第一句話加上<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />就OK了
6).單行文字居中與字體樣式問題
在div中一個層中只有一行文字,要讓這層中的文字居中,可設line-height的高度和層的高度一樣,注意這一層中的文字不能換行,此外,設了line-height時再給定字體樣式font:bold 14px "宋體";這時要把font:bold 14px "宋體";放在line-height的前面,否則字體樣式不顯示文字也不居中;或者將font:bold 14px "宋體";改成font-size:16px;font-weight:bold;font-family:"宋體";就OK了。
7).滑鼠滑上去的特殊效果
往往為了達到顯眼的效果,我們會寫到一些好看的效果,方法一在樣式表中寫:ul li a{border:1px solid red;}ul li a:hoverimg{filter:alpha(opacity=40在ul標簽中調用即可方法二:在樣式表中寫上:.hover img{filter:alpha(opacity=40);}在div中調用onmouseover="this.className='hover'"onmouseout="this.className=this.classtype"即可
8).IE6中高度不對問題
今天在div中給定了高度為1px,其它瀏覽器顯示正常,可是ie6中顯示的高度就不對了,這時我給樣式表中加了個font-size:0px;line-height:0px;就好了
9).ul在外框里margin-top不起作用的問題
在div大框子里用了ul作導航的時候為了合ul層居中顯示,設ul的樣式表為margin-top:-15px不起作用了,此時應該將div大框設定高度後給個line-height與height一樣的高度,ul層就自動居中了。
例如
10).ff中margin-top有時不起作用的問題
今天頭暈腦漲的把這問題給解決了,這幾天寫標網都有累似問題,可是一直都是換個寫法解決的,今天的這個辦法也不只可行試試還是可以的,在一個div外框層中給個寬度例如,#div_wrap{width:280px;height:100%;}
其次在這個框子里設一個.div_top{widh:100%;font:bold12px "宋體";height:24px;line-height:24px;}
.div_center{border:1px solid#dbdbdb;border-top:none;background:#fff;min-height:460px !important;height:auto!important;height:460px;overflow:visible;}
最後在這個div_center里套個ul li時經常會在ff中出問題,也就是在div_top與div_center中莫名的多了幾個像素的空格,這時給ul樣式表設個display:inline-table即可;
11).list-style-image的用法
div中經常用到新聞列表前面有圖標的樣式,有兩種簡單的方法
一.可以寫成ul.menu{width:100%;} ul.menuli{background:url(em_img/small_icon.jpg) 5px center no-repeat;list-style-position:inside;padding-left:18px;}即可在各瀏覽器正常顯示
二. 可以設ul.menu{width:80%;} ul.menuli{list-style-image:url(em_img/small_icon.jpg); }
此時新聞列表前的小圖標即可在ie6,ie7,ie8,ff中都正常顯示但,ie6需要不斷的刷新才能正常顯示小圖標;
12).
IE6 li:hover兼容問題
<scripttype="text/javascript"><!--//--><![CDATA[//><!--
sfHover =function() {
var sfEls = document.getElementById("nav").getElementsByTagName_r("LI");
for (var i=0; i<sfEls.length; i++) {
sfEls[i].onmouseover=function() {
this.className+=" sfhover";
}
sfEls[i].onmouseout=function() {
this.className=this.className.replace(new RegExp(" sfhover\b"), "");
}
}
}
if (window.attachEvent) window.attachEvent("onload", sfHover);
//--><!]>
</script>
13).ie6下支持position:absolute;
最近寫一個簡訊平台的頁面用到的底部固定的層,在ff和ie7,ie8下都是好的,可到ie6下就不行了,轉了整個地球終於出來了:
background-attachment:fixed; }
#bottomNav {background-color:#096; z-index:999; position:fixed; bottom:0; left:0;width:100%; _position:absolute;
_top: expression_r(documentElement.scrollTop+ documentElement.clientHeight-this.offsetHeight); overflow:visible; }
樣式表中調用即可!詳細請見「高度自適應屏幕尺寸!」
14).border:none;與border:0;的區別
1.性能差異
【border:0;】把border設為「0」像素雖然在頁面上看不見,但按border默認值理解,瀏覽器依然對border-width/border-color進行了渲染,即已經佔用了內存值。
【border:none;】把border設為「none」即沒有,瀏覽器解析「none」時將不作出渲染動作,即不會消耗內存值。
2.兼容性差異
兼容性差異只針對瀏覽器IE6、IE7與標簽button、input而言,在win、win7、vista 的XP主題下均會出現此情況。
【border:none;】當border為「none」時似乎對IE6/7無效邊框依然存在
【border:0;】當border為「0」時,感覺比「none」更有效,所有瀏覽器都一致把邊框隱藏
總結:
1. 對比border:0;與border:none;之間的區別在於有渲染和沒渲染,感覺他們和display:none;與visibility:hidden;的關系類似,而對於border屬性的渲染性能對比暫時沒找測試的方法,雖然認為他們存在渲染性能上的差異但也只能說是理論上。
2. 如何讓border:none;實現全兼容?只需要在同一選擇符上添加背景屬性即可
對於border:0;與border:none;個人更向於使用,border:none;,因為border:none;畢竟在性能消耗沒有爭議,而且兼容性可用背景屬性解決不足以成為障礙。
15).ie下。png的圖片不會有灰色背景出現
註:首推PNG8,即使在IE6中它的透明背景也能被正確顯示。PNG8使用的技巧是,輸出時把「雜邊」設置為和背景接近的顏色
1.幾經周折終於把ie6下.png有色圖問題解決了,原來IE6.0原本支持png8的索引色透明度,但不支持png或8位以上的alpha 透明度,在IE6.0下,非PNG8格式的透明圖片部分,會顯示為淡淡的灰綠色。在網頁中頭部加個代碼<!--[if IE 6]>
<script type="text/javascript" src=""></script>
<script src="js/DD_belatedPNG.js"></script>
<script>
DD_belatedPNG.fix('.png_bg');
</script>
<![endif]-->即可!
⑷ Ajax 跨域問題及其解決方案
主流的 前後端分離模式 下,當前端調用後台介面時,由於是在非同一個域下的請求,從而會引發 瀏覽器 的自我安全保護機制,最終結果是 介面成功請求並響應 ,但 前端不能正常處理該返回數據 。
因此,當 同時滿足 以下三個條件的情況下,就會出現跨域問題:
想要徹底解決跨域問題,只需要破壞以上三個條件的任一即可:
添加瀏覽器啟動參數: chrome --disable-web-security ,但是極不推薦這種解決方式。
Jsonp,全稱 JSON with Padding ,一種非官方的協議,而是一種約定;前端通過向後台發送 script 類型請求解決跨域,此時介面響應的 application/javascript 類型的數據會作為 callback 函數的參數進行處理。
所以,後台也需要做相應的處理。以 Java 為例,添加如下配置即可:
綜上, jsonp 請求存在以下幾個弊端:
用 Nginx 或 Apache 來代理調用方的請求( 客戶端變更為相對路徑請求,而非絕對路徑 ),此時對於瀏覽器來說,由於請求是同源的,因此就不存在跨域問題。
以 Java 應用為例,添加如下全局配置:
如果只想針對某個類下的介面,或者是某個具體的介面配置允許跨域,只需要在相應的地方添加註解 @CrossOrigin 即可。
如果配置了 nginx 作為代理伺服器,那麼只需要為 nginx 添加支持跨域請求即可:
Q1:瀏覽器在執行跨域請求時,是先執行後判斷,還是先判斷後執行?
A1:都有可能,這需要根據所發送的請求是 簡單請求 還是 非簡單請求 來判斷;如果是非簡單請求,瀏覽器每次在執行真正的請求之前,還會先發送一個 options 請求方式的預檢命令【 可設定緩存時長,取消每次請求都要預檢,提高效率,參考上面的服務端配置 】。關於兩種請求的區分及定義,參考下圖說明:
Q2:如果是允許帶( 被調用方 ) cookie 的跨域請求,此時服務端同樣配置為 Access-Control-Allow-Origin 等於 * ,前端是否還可以請求成功?
A2:不可以,此時要將 Access-Control-Allow-Origin 指定為 調用方 具體的域【 可以先取得調用方的域再動態配置,這樣就不存在多個域請求的限制問題 】,並且添加配置 Access-Control-Allow-Credentials 為 true 。