同源策略
同源策略規定:不同域的客戶端腳本在沒有明確授權的情況下,不能讀寫對象的資源。
同源和異源
不同域
- 協議不同(
HTTP
與HTTPS
) - 域名不同(頂級域,
www
域和子域) - 端口不同(比如
80
端口和81
端口)
同域
- 多了目錄,符號協議,域名,端口都相同
網頁授權
通過HTTP
響應頭返回字段設置的,設置字段如下:Access-Controll-Allow-Origin: http://www.demo.com
沙盒框架(Sandboxed frame
)
- 是對常規
<iframe>
表現行爲的擴展,它能讓頂級頁面對其嵌入的子頁面及這些子頁面的子資源設置一些額外的限制 - 通過
<iframe>
的參數實現限制Allow-scripts
:是否允許執行javascript腳本,沒有則不允許Allow-forms
: 是否允許使用form表單,沒有則不允許Allow-top-navigation
: 是否允許嵌入子頁面控制頂級窗口的地址跳轉,沒有則不允許Allow-same-origin
: 是否允許訪問同源數據,沒有則不允許
Flash
安全沙箱
- 分爲本地沙箱與遠程沙箱
- 類似同源策略,在同一域內的資源會被放到一個安全組下,稱爲安全沙箱
Web
站點通過crossdomain.xml
文件配置可以提供允許的跨域訪問本域上內容的權限(放置於站點根目錄)
<cross-domain-policy>
<allow-access-form domain=".youku.com" />
</cross-domain-policy>
Cookie
的安全策略
Domain
用於指定Cookie
的有效域Path
用於指定Cookie
的有效URL
路徑Secure
如果設置該屬性,僅在HTTPS
請求中提交Cookie
Http
其實是HttpOnly
, 如果設置該屬性,客戶端javascript無法獲取Cookie
的值
內容安全策略 (Content Security Polity, CSP)
通過編碼在HTTP響應頭中的指令來實施策略
Content-Security-Polity:script-src 'self' https://baidu.com
- CSP的一些指令
default-src
: 該指令在某種資源類型指定指令沒有被定義的情況下制定了所有資源類型的加載策略(即默認的資源加載策略)script-src
: 該指令指定了Web應用程序可以加載的腳本的域或URLobject-src
: 該指令制定了Web應用程序可以加載的插件,如Falshstyle-src
: 該指令制定了Web應用程序可以加載的CSS樣式表的域或URLimg-src
: 該指令指定了Web應用程序可以加載的圖片的域或URLmedia-src
: 該指令指定了Web應用程序可以加載的音視頻的域或URLframe-src
: 該指令指定了Web應用程序可以加載的框架的域或URLfont-src
: 該指令指定了Web應用程序可以加載的字體的域或URLconnect-src
: 該指令指定了Web應用程序可以加載的像XHR, WebSockets
, 以及EventSource
等腳本接口的域或URLplugin-types
: 該指令指定了哪些MIME類型的插件可以被加載(瀏覽器支持度不夠)form-action
: 該指令指定了HTML表單可以提交的URLS(瀏覽器支持度不夠)reflected-xss
: 該指令告訴瀏覽器開啓或關閉任何用於過濾或組織反射跨站腳本攻擊的啓發式算法,這相當於X-XSS-Protection
響應頭的效果(瀏覽器支持度不夠)
瀏覽器的緩存策略
前端緩存策略:
已開始生產的項目,用戶每次刷新的時候大多數與上次請求的數據一致。那麼服務器端的數據沒有更新,客戶端也沒有必要每次都去服務器端拉取數據,佔用服務器的帶寬。這時候需要前端的靜態文件緩存機制。以下以nginx
配置爲例(前提,已對nginx
有基本的瞭解)。
如何配置,請看下一篇 《nginx
緩存配置》
一、介紹
1、Last-Modified
在瀏覽器第一次請求某一個URL
時,服務器端的返回狀態碼會是200
,內容是你請求的資源,同時有一個Last-Modified
的屬性標記(在HttpReponse Header
),此文件在服務器端最後被修改的時間。
客戶端第二次請求此URL
的時,根據HTTP
協議的規定,瀏覽器會向服務器詢問是否被修改過(If-Modified-Since
在HttpRequest Header
)
如果服務器端的資源沒有變化,則自動返回HTTP
狀態碼爲304
(NotChanged
)內容爲空,這樣就節省了傳輸量,節省了帶寬。當服務器端代碼發生變化或重啓服務器時,則重新發送資源,如第一次請求時返回數據一樣。
2、ETag
Http
協議說明定義EFlag
爲“被請求變量的實體標記”,及服務器響應時會給URL
做標記,並在HttpReponse Header
返回給客戶端。同樣,如果Etag
沒有變,返回狀態碼爲304
。
當下次需要發Request
索要同一個URI
的時候,瀏覽器同時發出一個If-None-Match
報頭(Http RequestHeader
)此時包頭中信息包含上次訪問得到的Etag
。
If-None-Match:“5d8c72a5edda8d6a:3239“
,這樣,Client
端等於Cache
了兩份,服務器端就會比對2者的ETag
。如果If-None-Match
爲False
,不返回200
,返回304
(Not Modified) Response
。
3、Expries
緩存有效期。用於控制請求文件的有效時間,當請求數據在有效期內客戶端獲取數據是從緩存請求數據而不是從服務器。當緩存時間過期後,才從服務器更新數據。
4、Last-Modified
和Expires
Last-Modified
標識能夠節省一點帶寬,但是還是逃不掉髮一個HTTP
請求出去,而且要和Expires
一起用。而Expires
標識卻使得瀏覽器乾脆連HTTP
請求都不用發,比如當用戶F5或者點擊Refresh
按鈕的時候就算對於有Expires
的URI
,一樣也會發一個HTTP
請求出去,所以,Last-Modified
還是要用的,而且要和Expires
一起用。
5、Etag
和Expires
如果服務器端同時設置了Etag
和Expires
時,Etag
原理同樣,即與Last-Modified/Etag
對應的HttpRequestHeader
:If-Modified-Since
和If-None-Match
。我們可以看到這兩個Header
的值和WebServer
發出的Last-Modified
,Etag
值完全一樣;在完全匹配If-Modified-Since
和If-None-Match
即檢查完修改時間和Etag
之後,服務器才能返回304
.
6、Last-Modified
和Etag
注意:分佈式系統裏多臺機器間文件的last-modified
必須保持一致,以免負載均衡到不同機器導致比對失敗,分佈式系統儘量關閉掉Etag
(每臺機器生成的etag
都會不一樣)
Last-Modified
和ETags
請求的http
報頭一起使用,服務器首先產生Last-Modified/Etag
標記,服務器可在稍後使用它來判斷頁面是否已經被修改,來決定文件是否繼續緩存
7、Cache-Control:max-age=秒
和 Expries
Expries = 時間
,HTTP 1.0 版本,緩存的時間,允許客戶端在這個時間段之內不去檢查(發送請求)
max-age = 秒
,HTTP 1.1版本,資源在本地緩存多少秒
如果max-age
和 Expries
同時存在,則被Cache-Control:max-age
覆蓋。
Expires
的一個缺點就是,返回的到期時間是服務器端的時間,這樣存在一個問題,如果客戶端的時間與服務器的時間相差很大,那麼誤差就很大,所以在HTTP 1.1
版開始,使用Cache-Control: max-age=秒
替代。
Expires =max-age + “每次下載時的當前的request時間”
所以一旦重新下載的頁面後,expires
就重新計算一次,但last-modified
不會變化 .
二、過程
1.客戶端請求一個頁面(A)。
2.服務器返回頁面A,並在給A加上一個Last-Modified/ETag
。
3.客戶端展現該頁面,並將頁面連同Last-Modified/ETag
一起緩存。
4.客戶再次請求頁面A,並將上次請求時服務器返回的Last-Modified/ETag
一起傳遞給服務器。
5.服務器檢查該Last-Modified
或ETag
,並判斷出該頁面自上次客戶端請求之後還未被修改,直接返回響應304
和一個空的響應體。
具體事例請看: