cors和jsonp

本文目錄一覽:

【http】什麼是cors跨域

前端開發中,常常需要進行跨域請求。既然提到跨域,首先我們的知道什麼是「同源策略」。

同源策略限制從一個源加載的文檔或腳本如何與來自另一個源的資源進行交互。這是一個用於隔離潛在惡意文件的關鍵的安全機制。

如果協議,端口(如果指定了一個)和域名對於兩個頁面是相同的,則兩個頁面具有相同的源。

同一個源內,資源的訪問是很自由的。就跟在自己家中,想開冰箱開冰箱,想幹啥幹啥。如果你想訪問不同源的資源,可就沒那麼自由了,這就是跨域。

關於跨域,常用的JSONP應該都知道。JSONP的原理是什麼呢?我們來看看大神賀師俊的解釋:

很簡單,就是利用script標籤沒有跨域限制的「漏洞」(歷史遺迹啊)來達到與第三方通訊的目的。當需要通訊時,本站腳本創建一個script元素,地址指向第三方的API網址,並提供一個回調函數來接收數據(函數名可約定,或通過地址參數傳遞)。 第三方產生的響應為json數據的包裝(故稱之為jsonp,即json padding),這樣瀏覽器會調用callback函數,並傳遞解析後json對象作為參數。本站腳本可在callback函數里處理所傳入的數據。

可以知道JSONP就是個bug般的存在啊,如果你是一個有潔癖的程序員回想說:這不合理,這部乾淨。因此我們引出cors。

那麼,什麼是cors呢?

我們來看看互動百科的解釋:

CORS(跨來源資源共享)是一份瀏覽器技術的規範,提供了Web服務從不同網域傳來沙盒腳本的方法,以避開瀏覽器的同源策略,是JSONP模式的現代版。

維基百科的解釋(手動谷歌):

Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources (e.g. fonts) on a web page to be requested from another domain outside the domain from which the first resource was served.

這樣看來,其實嘛,cors就是一個規範,機制,基於這個規範,不同源之間才可以請求資源。相當於一個江湖規矩,大家都按規矩來嘛不是?不講規矩?信不信小拳拳捶你。

所以呢,要想使用cors跨域訪問,你就得講規矩。下面我們來看看有哪些規矩。

跨域資源共享標準( cross-origin sharing standard )允許在下列場景中使用跨域 HTTP 請求:

cors中有個術語叫 「簡單請求」 ,若請求滿足所有下述條件,則該請求可視為「簡單請求」:

使用下列方法之一:

之所以區分簡單請求,是因為cors需要處理一些「非簡單請求」,這種特殊處理叫做「預檢請求」。大人物來了,總要提前準備準備吧,封路啥的blabla。

預檢請求的作用是 提前獲知服務器是否允許該實際請求 。「預檢請求」的使用,可以 避免跨域請求對服務器的用戶數據產生未預期的影響 。

一張圖可以清晰看到提前發送預檢請求的cors請求

Request Headers:

Response Header:

cors在koa中的使用:

相關鏈接:

web前端跨域的一些解決方案

沒有歸納之前對跨域的一些說法是模糊的,什麼jsonp啊,跨域原理啊,心裏只有一個大概的說法,知道這個東西,然後用的時候直接百度Ctrl+C,後來閑下來決定整理一波這些知識點,需知其所以然。

那麼,其實這是瀏覽器對我們的一種保護機制,把壞人擋在門外。那麼,問題來了,我們怎麼確定門外的人到底是好人還是壞人呢?瀏覽器關上了壞人的一扇門,留給了我們好人一扇窗。

JSONP跟JSON沒有關係..就好像JavaScript和Java一樣

瀏覽器對script、img(這些標籤的請求方式都是 GET ,所以jsonp不支持 POST )這種標籤沒有限制,我們就可以這樣干

因此,實現CORS通信的關鍵是服務器。只要服務器實現了CORS接口,就可以跨源通信。

服務器端對於CORS的支持,主要就是通過設置 Access-Control-Allow-Origin 來進行的。如果瀏覽器檢測到相應的設置,就可以允許Ajax進行跨域的訪問。 更多有關跨域資源共享 CORS 的知識

瀏覽器中可以查看對應的響應頭,舉個例子,如下

服務端允許CORS,服務端需要針對接口設置的一系列響應頭 (Response Headers)

1.簡單請求

目前大多數情況都採用這種方式。簡單請求只需要設置 Access-Control-Allow-Origin 即可。滿足以下兩個條件,就屬於簡單請求。

2.非簡單請求

非簡單請求會發出一次預檢測請求,返回碼是204,預檢測通過才會真正發出請求,這才返回200。來看栗子:

非簡單請求需要根據不同情況配置不同的響應頭,一系列響應頭配置項見上方

這個說法相信不陌生,我們依然使用前端域名請求,然後有一個 中介商—代理 把這個請求轉發到真正的後端域名上,那也就不存在跨域問題了。

比較普遍的Nginx,簡單的配置一下就可以了。了解更多的配置信息: nginx詳解

然後前端這邊的請求地址是 ,然後Nginx監聽到地址是 localhost:9099/api 的請求,就幫我們轉發到真正的服務端地址

CORS與JSONP的使用目的相同,但是比JSONP更強大。JSONP只支持GET請求,CORS支持所有類型的HTTP請求。JSONP的優勢在於支持老式瀏覽器,以及在服務端同意jsonp方式時,可以向不支持CORS的網站請求數據。Nginx可以說是最方便的,不過需要部署Nginx才行,需要對服務器有一定的理解,不太適合剛入門的同學,當然也可以請後台同學幫忙部署。

window.postMessage(data,origin) 是 HTML5 的一個接口,專註實現不同窗口不同頁面的跨域通訊。

現在是這麼一個情況,由於同源策略的限制下, a.html 不能操作iframe( b.html )裏面的dom,那麼使用postMessage就可以解決這一情況

然後 b.html 頁面通過message事件監聽並接受消息:

這種方式只適合主域名相同,但子域名不同的iframe跨域。

比如主域名是 ,子域名是 ,這種情況下給兩個頁面設置相同的document.domain即document.domain = baidu.com 就可以訪問各自的window對象了。

前端跨域整理

不要再問我跨域的問題了

Network出現兩次相同請求?我來解答

Network中出現了兩個相同的請求(如圖),兩個發起了同樣的請求,花的時間卻不同,一個55ms,一個花了294ms。

什麼情況啊?研究了一番,我發現有一個地方是不同的,Request Method!

請求時間短的Request Method是OPTIONS,並且返回值為空。

請求時間長的Request Method是GET。

原以為ajax請求只有HTTP的Request Method只有GET與POST兩種,後來發現還有HEAD、PUT、DELETE、OPTIONS……的區別。

本地環境跑公司項目的時候,每次POST之前,為啥瀏覽器還偷偷給我來一次沒有返回的OPTIONS請求?

原來,瀏覽器在某些請求中,在正式通信前會增加一次HTTP查詢請求,稱為"預檢"請求(preflight)。

瀏覽器先詢問服務器,當前網頁所在的域名是否在服務器的許可名單之中,以及可以使用哪些HTTP動詞和頭信息字段。只有得到肯定答覆,瀏覽器才會發出正式的XMLHttpRequest請求,否則就報錯。

CORS是一個W3C標準,全稱是"跨域資源共享"(Cross-origin resource sharing)。

它允許瀏覽器向跨源服務器,發XMLHttpRequest請求,從而克服了AJAX只能 同源 使用的限制。

瀏覽器將CORS請求分為兩類:簡單請求(simple request)和非簡單請求(not-so-simple request)。

同時滿足以下條件,就是簡單請求:

對於簡單請求,瀏覽器直接發出CORS請求。具體來說,就是在頭信息之中,增加一個Origin字段。

Origin字段用來說明,本次請求來自哪個源(協議 + 域名 + 端口)。服務器根據這個值,決定是否同意這次請求。

如果Origin指定的源,不在許可範圍內,服務器會返回一個正常的HTTP回應。瀏覽器發現,這個回應的頭信息沒有包含Access-Control-Allow-Origin字段(詳見下文),就知道出錯了,從而拋出一個錯誤,被XMLHttpRequest的onerror回調函數捕獲。注意,這種錯誤無法通過狀態碼識別,因為HTTP回應的狀態碼有可能是200。

如果Origin指定的域名在許可範圍內,服務器返回的響應,會多出幾個頭信息字段。都以Access-Control- 開頭:

(1)Access-Control-Allow-Origin

該字段是必須的。它的值要麼是請求時Origin字段的值,要麼是一個*,表示接受任意域名的請求。

該字段可選。它的值是一個布爾值,表示是否允許發送Cookie。默認情況下,Cookie不包括在CORS請求之中。設為true,即表示服務器明確許可,Cookie可以包含在請求中,一起發給服務器。這個值也只能設為true,如果服務器不要瀏覽器發送Cookie,刪除該字段即可。

(3)Access-Control-Expose-Headers

該字段可選。CORS請求時,XMLHttpRequest對象的getResponseHeader()方法只能拿到6個基本字段:Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma。如果想拿到其他字段,就必須在Access-Control-Expose-Headers裏面指定。

非簡單請求是那種對服務器有特殊要求的請求,比如請求方法是PUT或DELETE,或者Content-Type字段的類型是application/json。

非簡單請求的CORS請求,會在正式通信之前,增加一次HTTP查詢請求,稱為"預檢"請求(preflight)。

瀏覽器先詢問服務器,當前網頁所在的域名是否在服務器的許可名單之中,以及可以使用哪些HTTP動詞和頭信息字段。只有得到肯定答覆,瀏覽器才會發出正式的XMLHttpRequest請求,否則就報錯。

在頁面域名與接口域名不一致的情況下,就出現了每次請求前先發送一個options請求的問題。

OPTIONS請求頭信息中,除了Origin字段,還至少會多兩個特殊字段:

(1)Access-Control-Request-Method

該字段是必須的,用來列出瀏覽器的CORS請求會用到哪些HTTP方法。

(2)Access-Control-Request-Headers

該字段是一個逗號分隔的字符串,指定瀏覽器CORS請求會額外發送的頭信息字段。

至於其他亂七八糟的字段,現在的我還用不到也不懂,將會慢慢深入了解。

服務器收到預檢請求後,檢查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以後,確認允許跨源請求,就可以做出回應。

上面的HTTP回應中,關鍵的是Access-Control-Allow-Origin字段,表示 可以請求數據。該字段也可以設為星號,表示同意任意跨源請求。

如果瀏覽器否定了"預檢"請求,會返回一個正常的HTTP回應,但是沒有任何CORS相關的頭信息字段。這時,瀏覽器就會認定,服務器不同意預檢請求,因此觸發一個錯誤,被XMLHttpRequest對象的onerror回調函數捕獲。控制台會打印出如下的報錯信息。

XMLHttpRequest cannot load

Origin is not allowed by Access-Control-Allow-Origin.

其他字段中 Access-Control-Max-Age 用來指定本次預檢請求的有效期,單位為秒。該字段可選。

CORS與JSONP的使用目的相同,但是比JSONP更強大。

JSONP只支持GET請求,JSONP的優勢在於支持老舊瀏覽器。

解決Network出現兩次相同請求的問題使用簡單請求就不會遇到了。

前端跨域方式有哪些

處理跨域方法一——JSONP

1.JSONP原理

利用script元素的這個開放策略,網頁可以得到從其他來源動態產生的 JSON 數據。JSONP請求一定需要對方的服務器做支持才可以。

2.JSONP和AJAX對比

JSONP和AJAX相同,都是客戶端向服務器端發送請求,從服務器端獲取數據的方式。但AJAX屬於同源策略,JSONP屬於非同源策略(跨域請求)

3.JSONP優缺點

JSONP優點是兼容性好,可用於解決主流瀏覽器的跨域數據訪問的問題。缺點是僅支持get方法具有局限性。

4.JSONP的流程(以第三方API地址為例,不必考慮後台程序)

聲明一個回調函數,其函數名(如fn)當做參數值,要傳遞給跨域請求數據的服務器,函數形參為要獲取目標數據(服務器返回的data)。

創建一個

服務器接收到請求後,需要進行特殊的處理:把傳遞進來的函數名和它需要給你的數據拼接成一個字符串,例如:傳遞進去的函數名是fn,它準備好的數據是fn([{「name」:「jianshu」}])。

最後服務器把準備的數據通過HTTP協議返回給客戶端,客戶端再調用執行之前聲明的回調函數(fn),對返回的數據進行操作。

處理跨域方法二——CORS

1.CORS原理

整個CORS通信過程,都是瀏覽器自動完成,不需要用戶參與。對於開發者來說,CORS通信與同源的AJAX通信沒有差別,代碼完全一樣。瀏覽器一旦發現AJAX請求跨源,就會自動添加一些附加的頭信息,有時還會多出一次附加的請求,但用戶不會有感覺。因此,實現CORS通信的關鍵是服務器。只要服務器實現了CORS接口,就可以跨源通信。

2.CORS優缺點

CORS要求瀏覽器(IE10)和服務器的同時支持,是跨域的根本解決方法,由瀏覽器自動完成。

優點在於功能更加強大支持各種HTTP Method,缺點是兼容性不如JSONP。

處理跨域方法三——WebSocket

Websocket是HTML5的一個持久化的協議,它實現了瀏覽器與服務器的全雙工通信,同時也是跨域的一種解決方案。WebSocket和HTTP都是應用層協議,都基於 TCP 協議。但是 WebSocket 是一種雙向通信協議,在建立連接之後,WebSocket 的 server 與 client 都能主動向對方發送或接收數據。同時,WebSocket 在建立連接時需要藉助 HTTP 協議,連接建立好了之後 client 與 server 之間的雙向通信就與 HTTP 無關了。

原生WebSocket API使用起來不太方便,我們使用Socket.io,它很好地封裝了webSocket接口,提供了更簡單、靈活的接口,也對不支持webSocket的瀏覽器提供了向下兼容。

處理跨域方法四——postMessage

如果兩個網頁不同源,就無法拿到對方的DOM。典型的例子是iframe窗口和window.open方法打開的窗口,它們與父窗口無法通信。HTML5為了解決這個問題,引入了一個全新的API:跨文檔通信 API(Cross-document messaging)。這個API為window對象新增了一個window.postMessage方法,允許跨窗口通信,不論這兩個窗口是否同源。postMessage方法的第一個參數是具體的信息內容,第二個參數是接收消息的窗口的源(origin),即"協議 + 域名 + 端口"。也可以設為*,表示不限制域名,向所有窗口發送。

原創文章,作者:IUX21,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/128210.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
IUX21的頭像IUX21
上一篇 2024-10-03 23:24
下一篇 2024-10-03 23:24

相關推薦

  • CORS解決跨域問題

    一、CORS的概述 CORS是Cross-Origin Resource Sharing(跨域資源共享)的縮寫,它是一種機制,讓Web應用程序在瀏覽器中與其他域之間進行安全的跨域訪…

    編程 2025-04-24
  • 探究no-cors

    一、nocor什麼意思 no-cors是一個Fetch API的設置選項,它表示請求將不會設置CORS相關的頭信息。這意味着該請求不會跨域,並且不會向服務器發送帶有cookie、H…

    編程 2025-04-12
  • 深入剖析jsonp跨域

    一、jsonp跨域是什麼 1、由來 在Web應用中,為了保證用戶瀏覽的速度,許多網頁會採用Ajax技術在頁面上進行部分刷新,在這個過程中,為了保護用戶的信息和系統的安全,服務器放置…

    編程 2025-01-11
  • 如何解決跨域資源共享(CORS)問題?

    一、什麼是跨域資源共享問題? Web應用程序通常會從不同的域(域名、端口或協議)請求數據。當瀏覽器在某個域上運行腳本時,它被限制只能腳本來源的域以及和該域共享同一來源的域(同源策略…

    編程 2024-12-31
  • jsonp和javascript的簡單介紹

    本文目錄一覽: 1、jsonp跨域的原理是什麼? 2、jsonp原理,以及為什麼不是真正的ajax 3、如何用原生js發送jsonp請求 4、JSONP是什麼意思 jsonp跨域的…

    編程 2024-12-22
  • CORS 錯誤詳解

    一、什麼是CORS? CORS(Cross-Origin Resource Sharing)是一種機制,它使用額外的HTTP頭來告訴瀏覽器,讓運行在一個origin (domain…

    編程 2024-12-22
  • CORS跨域資源共享漏洞全方位了解

    一、CORS跨域資源共享漏洞驗證 CORS(Cross-Origin Resource Sharing)跨域資源共享標準是W3C的一個標準,它允許Web應用程序在跨域服務器上請求資…

    編程 2024-12-20
  • 如何正確配置koa2-cors跨域

    一、什麼是跨域 跨域,指的是在同一網站的不同頁面之間,或者不同網站之間,發起網絡請求時的限制。如果你從一個網站的頁面獲取數據並想在另一個網站上使用,你將會受到跨域問題的限制。 例如…

    編程 2024-12-16
  • 跨域資源共享(CORS)完全指南

    在當前的Web開發中,跨域資源共享(CORS)是一個非常熱門的話題。由於瀏覽器的同源策略的限制,跨域資源訪問在很多情況下都會受到限制。為了解決這個問題,CORS應運而生,它允許服務…

    編程 2024-12-16

發表回復

登錄後才能評論