目錄
問題現象與描述
解決辦法
原理解析
什么是CORS
瀏覽器跨域請求限制
跨域問題解決方法
跨域請求流程
瀏覽器請求分類解析
http請求方法簡介
問題現象與描述
重慶軟航科技有限公司提供了一套針對針對word、excel等流式文件轉換成PDF版式文件并進行版式文件在線簽章的一個方案,給方案做了一個應用示例,該示例在完成流式文件轉成PDF版式文件之后展示了一個在線閱讀轉換后PDF文件并在線簽章的相關功能。
但是在tongweb上部署之后發現該示例完成word轉PDF功能后的在線查看PDF時功能異常,瀏覽器中F12調試 發現狀態信息不為200而是 CORS error,如下圖所示:
該功能對應的請求 已配置請求頭信息:Access-Control-Allow-Origin為*
查看詳細的信息時發現:Referrer Policy為same-origin:
且 該應用在tomcat中 部署時并未出現此類異常,因此可以斷定示例本身是沒有問題的。
猜想可能是由于tongweb的配置影響了。
說一下示例所需要的資源部署情況:將其需要的軟航電子簽章系統、軟航版式文檔簽批系統、軟航文檔轉換系統以及軟航提供的結合這幾個一體化應用示例都部署到了同一臺服務器的tongweb上了。
解決辦法
打開tongweb 管理控制臺,在【WEB容器配置】中選擇【HTTP通道管理】選擇【tong-http-listener】:
下拉到【其他設置】:
在其他設置這里有一個:禁用HTTP請求方法
將禁用的OPTIONS方法放開(勾選取消掉):
之后 重啟tongweb ,再試就可以解決 CORS error 問題了。
原理解析
什么是CORS
CORS:即跨域(Cross-Origin Resource Sharing, CORS)是一種安全策略,由瀏覽器 enforced,限制跨域 HTTP 請求,指在一個域下的網頁嘗試訪問另一個域下的資源。在web應用中服務器地址、端口、項目但凡有一個不同,訪問的資源不是自己的,那就屬于跨域。例如部署在A服務器上的appA項目,那么 在appA中訪問 B服務器上的appB?,或者訪問服務器A上的其他應用appx 都屬于跨域。
跨域問題主要發生在瀏覽器端,服務器端由于協議設計的原因,不存在跨域問題。瀏覽器端跨域請求主要涉及到同源策略(Same-Origin Policy),同源策略限制了從一個源加載的文檔或腳本與另一個源的資源進行交互。
瀏覽器跨域請求限制
瀏覽器默認是禁用跨域請求的,主要體現在以下方面:
(1)HTTP 請求方法:通常只允許 GET、POST 和 HEAD 請求。
(2)HTTP 頭信息:無法發送 Cookie、HTTP 認證信息(如 Basic Auth)等。
(3)HTTP 響應:無法讀取非簡單響應內容,如 JSONP 只支持 JSON 格式。
跨域問題解決方法
(1)同源策略:通過 HTML5 的 window.postMessage 方法實現跨域通信。
(2)CORS:服務器設置 Access-Control-Allow-Origin 等響應頭,允許特定域訪問資源。
(3)JSONP:通過動態創建 script 標簽,利用其不受同源策略限制的特性實現跨域請求。
(4)代理服務器:通過設置一個代理服務器,實現請求轉發和響應返回。
跨域請求流程
(1)瀏覽器發送預檢請求(Preflight Request):詢問服務器是否允許該跨域請求。
(2)服務器響應預檢請求:如果允許,返回相應的 CORS 響應頭。
(3)瀏覽器發送實際請求:攜帶 CORS 響應頭信息,如 Access-Control-Allow-Origin。
瀏覽器請求分類解析
瀏覽器發送預檢請求以及實際發送請求時就需要對瀏覽器請求做分類。 瀏覽器請求使用的是HTTP協議時,請求分類主要有:
HTTP 1.0: GET、POST、HEAD
HTTP 1.1: GET、POST、HEAD、[OPTIONS、PUT、PATCH、DELETE、TRACE、CONNECT]
在本次遇到的問題中已經設置好了?攜帶 CORS 響應頭信息,如 Access-Control-Allow-Origin ,且tomcat中異常,可以肯定應用本身是設定好的。而服務器響應預檢請求的時候實際是由 tomcat、tongweb這種應用服務器中間件來處理的。那么也就是說但凡瀏覽器發送的請求類型被應用服務器本身攔截了,那么必然是會出現跨域問題的,這時就需要讓應用服務器允許對應的請求才行。
http請求方法簡介
上述提到的瀏覽器請求分類,實際就是常說的http請求方法。主要http 請求方法介紹如下:
- get:用于從服務器獲取資源,例如請求一個網頁或圖片。這是最常見的請求方法,用于讀取或下載數據。
- head:與GET方法類似,但服務器在響應中只返回HTTP頭部信息,不返回實際數據。這通常用于檢索資源的元信息。
- post:用于向服務器提交數據以供處理,例如表單提交或文件上傳。POST請求通常用于添加新資源或更新現有資源。
- put:用于更新服務器上的現有資源。客戶端發送PUT請求時,會包含一個指定資源的新表示,服務器將用這個新表示替換原有資源。
- delete:用于請求服務器刪除指定的資源。
- connect:用于建立到服務器的隧道化連接,通常用于代理服務器。
- options:用于獲取關于資源所支持通信選項的信息。服務器在響應中會包含一個Allow頭,列出支持的所有請求方法。
- trace:用于追蹤請求-響應的傳輸路徑,通常用于調試目的。
根據瀏覽器調試的信息可以看到當前問題的網絡信息里 確實是有兩次請求?:第一次請求時 http請求的方法類型為:options 也就是前文提到的?瀏覽器發送預檢請求(Preflight Request):詢問服務器是否允許該跨域請求。
第二次才是 實際請求:
?所以在tongweb 管理控制臺里 設置?【WEB容器配置】中選擇【HTTP通道管理】選擇【tong-http-listener】里開放Options方法 就可以解決當下遇到的問題了。