如何修復WordPress中的CORS錯誤?

錯誤型別:
HTTP錯誤
錯誤名稱:
CORS错误
英文名稱:
Access to XMLHttpRequest at '……' from origin '…..' has been blocked by CORS policy
錯誤描述:
默认情况下,Web浏览器使用同源安全策略允许源自同一服务器的所有请求。否则……
錯誤變體:
Access-Control-Allow-Origin' header has a value '…..' that is not equal to the supplied origin.
Origin '….' is not allowed by Access-Control-Allow-Origin. Status code: 401
XMLHttpRequest cannot load '.....' due to access control checks
更多資訊

如何修復WordPress中的CORS錯誤?

只要您以簡單的方式使用WordPress網站,它就可以完美執行。當您想要新增其他功能和第三方指令碼時,它會給您帶來不同型別的錯誤。在我們之前的文章中,我們已經解釋了使用Cloudflare時發生WP-Cron的問題。同樣,CORS錯誤是許多使用者難以修復的另一個流行的WordPress錯誤。

在本文中,我們將探討什麼是CORS以及如何修復WordPress中的CORS錯誤。

什麼是CORS?

CORS代表跨域資源共享。預設情況下,Web瀏覽器使用同源安全策略允許源自同一伺服器的所有請求。以下是來自Wikipedia的同源策略的精確定義:

根據該政策,網路瀏覽器允許包含在第一個網頁中的指令碼訪問第二個網頁中的資料,但前提是兩個網頁具有相同的來源。——維基百科

現在您可以輕鬆理解跨域的目的。它允許您從另一個域或伺服器成功載入指令碼和其他資源。下面是一張來自MDN的精美圖片,解釋了同源請求和跨源請求的概念。

CORS跨域資源請求示意圖

CORS示例和檢視錯誤

假設您正在開啟一個頁面https://site1.com/page1 ,該頁面具有嵌入式JavaScript並從https://site2.com/page2呼叫它。CORS會告訴瀏覽器站點1是否允許來自站點2的跨域請求。否則,瀏覽器將阻止該請求並在控制檯中顯示與CORS相關的錯誤。

CORS的最佳示例是在您的網站上使用來自第三方域的廣告指令碼。如果您在伺服器上不允許CORS,Chrome、Firefox、Safari和Edge等瀏覽器將阻止廣告指令碼。當您看到頁面上沒有載入廣告或任何其他輸出時,右鍵單擊頁面並選擇“檢查”選項。這將開啟瀏覽器的開發者控制檯並轉到“控制檯”部分。

您將看到顯示403401狀態程式碼或沒有狀態程式碼的錯誤的不同型別的錯誤。例如,下面是谷歌瀏覽器中顯示的控制檯錯誤,錯誤清楚地表明“Access to XMLHttpRequest at ‘……’ from origin ‘…..’ has been blocked by CORS policy”。您還可以看到錯誤旁邊的原因,指出“The  ‘Access-Control-Allow-Origin’ header has a value ‘…..’ that is not equal to the supplied origin.”

Google Chrome中的CORS錯誤

Google Chrome中的CORS錯誤

在Mac Safari瀏覽器中開啟同一頁面時,將顯示不同的錯誤,如下所示。它將錯誤顯示為“Origin ‘….’ is not allowed by Access-Control-Allow-Origin. Status code: 401”。您還可以看到諸如“XMLHttpRequest cannot load ‘…..’ due to access control checks”之類的錯誤。

Safari瀏覽器中的CORS錯誤

Safari瀏覽器中的CORS錯誤

每當您看到與訪問控制檢查相關的控制檯錯誤時,您可以放心地假設它們與CORS問題有關。結果,您的指令碼將無法載入,您將看不到頁面上的廣告或預期結果。

修復WordPress中的CORS錯誤

現在您瞭解了什麼是CORS以及如何在瀏覽器控制檯中查詢相關錯誤。下一步是修復錯誤,以便您的頁面在瀏覽器上載入時不會出現任何錯誤。簡單來說,您必須在.htaccess檔案中新增以下程式碼,以允許在您的伺服器上進行跨域資源共享。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *
Access-Control-Allow-Origin: *

根據場景,您可以通過三種不同的方式實現此目的。

1. 允許所有站點

這是允許CORS的最常見方式。如果您想在您的站點上允許任何第三方伺服器請求,請在您的htaccess檔案中新增以下程式碼。* 用作允許任何第三方域的萬用字元。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<ifModule mod_headers.c>
Header set Access-Control-Allow-Origin: *
</ifModule>
<ifModule mod_headers.c> Header set Access-Control-Allow-Origin: * </ifModule>
<ifModule mod_headers.c>
Header set Access-Control-Allow-Origin: *
</ifModule>

2.允許特定域

不建議使用上述方法,因為任何劫持者都可能在您的網站上注入惡意指令碼檔案並造成麻煩。正確的做法是隻允許來自您需要的域的跨域資源共享。您可以將 * 替換為域的名稱,如下所示:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<ifModule mod_headers.c>
Header set Access-Control-Allow-Origin: https://site2.com
</ifModule>
<ifModule mod_headers.c> Header set Access-Control-Allow-Origin: https://site2.com </ifModule>
<ifModule mod_headers.c>
Header set Access-Control-Allow-Origin: https://site2.com
</ifModule>

不幸的是,這並不容易,因為您需要伺服器端編碼來驗證標頭訪問控制中允許的域。因此,許多WordPress使用者使用選項 #1,因為它不需要任何額外的編碼。

3.允許來自所有伺服器的特定檔案

最後一個選項是限制您要允許來自第三方伺服器的檔案型別。為此,您可以使用以下程式碼指示htaccess檔案中允許的檔案型別。

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<IfModule mod_headers.c>
<FilesMatch "\.(png|css|js)$">
Header set Access-Control-Allow-Origin: *
</FilesMatch>
</IfModule>
<IfModule mod_headers.c> <FilesMatch "\.(png|css|js)$"> Header set Access-Control-Allow-Origin: * </FilesMatch> </IfModule>
<IfModule mod_headers.c>
  <FilesMatch "\.(png|css|js)$">
    Header set Access-Control-Allow-Origin: *
  </FilesMatch>
</IfModule>

此程式碼將允許來自任何伺服器的PNG影象、CSS和JS檔案。您可以新增字型和其他影象檔案型別以允許它們在CORS中使用。

其他注意事項

在WordPress中允許跨域資源共享時,您可能需要注意一些額外的注意事項。

  • 一些託管公司需要您禁用他們的快取才能使CORS正常工作。例如,如果您在SiteGround上,則需要在“站點工具 > 速度 > 快取”部分下禁用NGINX直接交付。
  • 當使用Cloudflare或任何其他具有快取設定的CDN時,您可能需要完全清除快取,以使更改從源伺服器中反映出來。
  • 在使用HTTP和HTTPS協議時,CORS也會產生問題。這通常會在瀏覽器控制檯中顯示為混合內容錯誤,您需要在您的站點上強制使用HTTPS以阻止其他協議。
  • 另一個考慮是從子域向主域提供靜態資源和其他資源。這將完美地工作,因為子域和主域通常都在同一個源伺服器上。但是,根據伺服器上的設定,它也可能會產生問題。您可以通過特別提及子域來解決此問題,如上面選項 #2 中所述。

評論留言