単純なプロキシ実装例

提供: svg2wiki
2025年8月12日 (火) 02:45時点におけるAdmin (トーク | 投稿記録)による版

移動: 案内, 検索

この例は、PHPによる かなり単純なCORSプロキシの実装例です。よりセキュリティに配慮した実装が必要なケースがありますので、クロスオリジンアクセスの他の実装を参照の上利用を検討してください。


svgMap.jsの初期化

<!doctype html>
<html>
...
<script type="module">
import { CorsProxy } from 'https://cdn.jsdelivr.net/gh/svgmap/svgmapjs@latest/CorsProxyModule.js';
import { svgMap } from 'https://cdn.jsdelivr.net/gh/svgmap/svgmapjs@latest/SVGMapLv0.1_r18module.js';
window.svgMap=svgMap
var corsProxy = new CorsProxy();

// プロキシの設定
var proxyPath = "https://..url..of../simpleCORSproxy.php?file=";

corsProxy.setService(proxyPath, null, true, true); // 第4パラメータをtrueにするとアクセス先URLをエンコードする
window.corsProxy = corsProxy;
svgMap.setProxyURLFactory(null,null,null, corsProxy.getURLfunction(), true); // ビットイメージ非線形図法変換の時のみプロキシを使う
</script>
...
</html>

  • corsProxy.jsはクロスオリジンアクセス#corsProxy.jsを参照
  • corsProxy.setServiceの、requireEncoding フラグはtrueにします。
    • 本php実装ではfileクエリに記載される取得先URLがURLエンコードされていることを想定しているため

ソースコード

  • simpleCORSproxy.php
  • proxyへのアクセスに際して、refererリクエストヘッダが必要なコードになっています。
    • refererヘッダによる制限のためには、if (preg_match("|^https?://svgmap\.org|", $referer) .. の行を適宜書き換えてください

<?php

// 許可するリファラードメインの正規表現リスト
// 必要に応じてここにドメインを編集・追加してください。
$allowedReferers = [
    '#^https?://www\.svgmap\.org/#',
    // '#^https?://example\.com/#',
];

if (isset($_GET['file'])) {
    $fileUrl = urldecode($_GET['file']);
    $referer = $_SERVER['HTTP_REFERER'] ?? '';

    // 許可されたリファラーからのアクセスかチェック
    $isAllowed = false;
    foreach ($allowedReferers as $pattern) {
        if (preg_match($pattern, $referer)) {
            $isAllowed = true;
            break;
        }
    }

    // リファラーが無効な場合はアクセスを拒否
    if (!$isAllowed) {
        header("HTTP/1.1 403 Forbidden");
        echo "Error: Access denied. Invalid or missing Referer.";
        exit();
    }

    // cURLセッションの初期化と設定
    $ch = curl_init();
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_URL => $fileUrl,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_CONNECTTIMEOUT => 10,
        CURLOPT_USERAGENT => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
    ]);

    $contentData = curl_exec($ch);

    if ($contentData === false) {
        header("HTTP/1.1 500 Internal Server Error");
        echo "Error: Could not retrieve content.";
        exit();
    }

    // MIMEタイプを自動で判定して設定
    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $contentType = finfo_buffer($finfo, $contentData);
    finfo_close($finfo);

    // テキスト系ファイルの場合はUTF-8を指定
    if (strpos($contentType, 'text/') === 0 || $contentType === 'application/json') {
        header("Content-Type: " . $contentType . "; charset=UTF-8");
    } else {
        header("Content-Type: " . $contentType);
    }
    
    echo $contentData;
    curl_close($ch);

} else {
    header("Content-Type: text/html; charset=UTF-8");
    echo "<h1>Content Proxy</h1><p>This proxy requires a 'file' GET parameter with a URL-encoded content URL.</p>";
}

個人用ツール
名前空間

変種
操作
案内
ツール
Translate