同源
1995年,同源政策由 Netscape 公司引入瀏覽器。目前,所有瀏覽器都實行這個政策。同源策略:最初,它的含義是指,A網頁設置的 Cookie,B網頁不能打開,除非這兩個網頁"同源"。所謂"同源"指的是"三個相同":域名、協議、端口號相同即爲同源,同源政策的目的,是爲了保證用戶信息的安全,防止惡意的網站竊取數據。
不受同源策略限制:
- 頁面中的鏈接,重定向以及表單提交是不會受到同源策略限制的。
- 跨域資源的引入是可以的。但是js不能讀寫加載的內容。如嵌入到頁面中的script、img、link、iframe等。
跨域
同源策略雖然保證了用戶信息的安全,但同時也使得實際開發中出現一些影響。例如實際開發中,將服務器端架設到一臺服務器中,把客戶端頁面放到另外一個單獨的服務器。那麼這時候就會出現不同源的情況,這就需要使用到跨域 。
# 項目s1
def index(request):
date = {"name":"app1"}
ret = JsonResponse(date)
ret['Access-Control-Allow-Origin'] = "http://127.0.0.1:8001" # 設置響應頭
return ret
<!--項目s2-->
<script>
$("#bt").click(function () {
$.ajax({
url:"http://127.0.0.1:8000/index/",
type:"post",
data:{"a":"1"},
success(res){
console.log(res)
}
})
})
</script>
CORS跨域資源共享
CORS需要瀏覽器和服務器同時支持。目前,所有瀏覽器都支持該功能,IE瀏覽器不能低於IE10。
整個CORS通信過程,都是瀏覽器自動完成,不需要用戶參與。對於開發者來說,CORS通信與同源的AJAX通信沒有差別,代碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有感覺。因此,實現CORS通信的關鍵是服務器。只要服務器實現了CORS接口,就可以跨源通信。瀏覽器將CORS請求分成兩類:簡單請求(simple request)和非簡單請求(not-so-simple request),只要同時滿足以下兩大條件,就屬於簡單請求。反之就屬於非簡單請求(複雜請求)。
簡單請求
條件1:
請求方法是以下三種方法之一
- HEAD
- GET
- POST
條件2:
HTTP的頭信息不超出以下幾種字段
-
Accept
-
Accept-Language
-
Content-Language
-
Last-Event-ID
-
Content-Type:
只限於三個值application/x-www-form-urlencoded、multipart/form-data、text/plain
複雜請求
複雜請求時,首先會發送“預檢”請求,如果“預檢”成功,則發送真實數據。如果複雜請求,則服務端需要設置允許某請求Access-Control-Request-Method,否則“預檢”不通過。如果複雜請求設置了請求頭,則服務端需要設置允許某請求頭Access-Control-Request-Headers,否則“預檢”不通過
Django中解決跨域
# 返回結果中添加響應頭
def index(request):
obj=HttpResponse(json.dumps({'num':'123'}))
# res['Access-Control-Allow-Headers'] = 'content-type'
# res['Access-Control-Allow-Methods'] = 'PUT'
# obj['Access-Control-Allow-Origin']='*'
obj['Access-Control-Allow-Origin']='http://127.0.0.1:8001'
return obj
# 中間件中添加響應頭
from django.utils.deprecation import MiddlewareMixin
class MyCorsMiddle(MiddlewareMixin):
def process_response(self, request, response):
# response['Access-Control-Allow-Origin']='http://127.0.0.1:8001'
response['Access-Control-Allow-Origin'] = '*'
if request.method == 'OPTIONS':
# 所有的頭信息都允許
response['Access-Control-Allow-Headers'] = '*'
return response