Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124

處理圖床 HTTP 混合內容問題

近期因為客戶的網站改版,發現客戶使用的網站圖片來源是沒有 SSL 加密 (http),導致直接使用 <img src="" /> 時,會產生以下錯誤訊息:

Mixed Content: The page at ‘https://yoursite.dev/’ was loaded over HTTPS, but requested an insecure image ‘http://webhost.com/image.jpg’. This request has been blocked; the content must be served over HTTPS.

因為客戶存放圖片的伺服器並沒有開放 443 連接埠,因此只把網址改為 https://webhost.com/image.jpg 會出現 Connection Refused 的錯誤。後來觀察了客戶的舊網站,才發現客戶將網址包裝成 https://service.com/?url=http://webhost.com/image.jpg,用來解決這個問題。

因為以後可能會用到,所以先筆記一下。

額外架設將要求轉為 SSL 加密過的服務

首先在另一台主機安裝 guzzle 的 Composer 套件,並新增一個 index.php 檔案。

composer require guzzlehttp/guzzle
touch index.php

編輯 index.php,加入以下的程式碼:

<?php

require_once 'vendor/autoload.php';

use GuzzleHttp\Client;

// 從 url 參數取得圖片網址的參數
$imagePath = $_GET['url'];

// 篩選圖片網址,避免安全性問題

if (filter_var($imagePath, FILTER_VALIDATE_URL) && parse_url($imagePath, PHP_URL_SCHEME) === 'http' && parse_url( $imagePath, PHP_URL_HOST) === '指定的網域' ) {

    // 建立 Guzzle HTTP 用戶端
    $client = new Client();

    try {
        // 從 HTTP 主機比對資料
        $response = $client->get($imagePath);

        // 取得圖片內容與內容格式
        $imageContent = $response->getBody();
        $contentType = $response->getHeaderLine('Content-Type');

        // 設定 Content-Type 並輸出圖片
        header('Content-Type: ' . $contentType);
        echo $imageContent;
    } catch (Exception $e) {
        // 輸出錯誤訊息,debug 用
        header('HTTP/1.1 404 Not Found');
        echo 'Images not found';
    }
} else {
    // 如果不符合篩選規則,輸出 403 錯誤
    header('HTTP/1.1 403 Forbidden');
    echo 'Invalid URL or not from the allowed source.';
}
Eric Chuang
Eric Chuang

正職是廣告行銷人員,因為 Google Tag Manager 的關係開始踏入網站製作的領域,進一步把 WordPress 當成 PHP + HTML + CSS + JavaScript 的學習教材。此外,因為工作的關係,曾經用 Automattic 的 Underscores (_s) 替客戶與公司官網進行全客製化佈景主題開發。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料