一、架構
我們有的時候會遇到這樣的情況,我們的 wordpress 的服務器是提供 http 服務的,我們現在需要在前面添加一個負載均衡,配置用戶和負載均衡之間使用 https 協議,負載均衡到 apache 之間使用 http 協議
二、問題
2.1、遇到的問題
如果我們這樣設置的話,會導致一些頁面不正常,因爲 css 文件還有 js 文件會被瀏覽器攔截,這是因爲瀏覽器爲了安全,會攔截 https 頁面中的一些 http 鏈接。
https://developers.google.com/web/fundamentals/security/prevent-mixed-content/fixing-mixed-content
2.2、造成原因的原理
據我所瞭解,當 wordpress 會根據用戶的請求,返回的文檔中包含不同的鏈接:
如果用戶使用 http 訪問 wordpress,wordpress 返回的文檔中的鏈接,協議都是 http 的,
如果用戶使用 https 訪問 wordpress,wordpress 返回的文檔中的鏈接,協議都是 https 的。
我們目前遇到的情況就是,ELB 使用 http 訪問 wordpress,所以 wordpress 返回給 ELB 的鏈接是 http 的,然後返回給瀏覽器這些鏈接,瀏覽器就使用 http 向 ELB,這就導致了上面的問題。
三、解決
我們需要添加一些配置,告訴 wordpress,當用戶使用 http 請求的時候,給它返回 https 協議的鏈接。
3.1、修改 apache 配置文件
<VirtualHost *:80>
...
SetEnvIf x-forwarded-proto https HTTPS=on
RewriteEngine On
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI}
...
3.2、對於 nginx
修改爲如下
server {
...
location / {
...
proxy_set_header X-Forwarded-Protocol $scheme;
}
}
3.2、修改 wordpress 配置文件
修改文件wp-config.php
,在最後新增如下內容
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
$_SERVER['HTTPS']='on';
下面這部分內容,我添加與否好像效果是一樣的,如果沒有生效,大家可以添加在上面配置文件的前面
define('WP_SITEURL', 'https://' . $_SERVER['HTTP_HOST'] . '/');
define('WP_HOME', 'https://' . $_SERVER['HTTP_HOST'] . '/');