単純なプロキシ実装例
提供: svg2wiki
				
								
				(版間での差分)
				
																
				
				
								
				|  (→ソースコード) |  (→ソースコード) | ||
| (1人の利用者による、間の1版が非表示) | |||
| 32行: | 32行: | ||
| == ソースコード == | == ソースコード == | ||
| * simpleCORSproxy.php | * simpleCORSproxy.php | ||
| + | ** >PHP7.4 | ||
| * proxyへのアクセスに際して、refererリクエストヘッダが必要なコードになっています。 | * proxyへのアクセスに際して、refererリクエストヘッダが必要なコードになっています。 | ||
| <!-- * refererヘッダを用いてアクセス制限をかける場合、プロキシはwebAppと別ドメインになっている必要があります。(同一ドメインではrefererヘッダが付与されない) | <!-- * refererヘッダを用いてアクセス制限をかける場合、プロキシはwebAppと別ドメインになっている必要があります。(同一ドメインではrefererヘッダが付与されない) | ||
| 48行: | 49行: | ||
| if (isset($_GET['file'])) { | if (isset($_GET['file'])) { | ||
| − |      $fileUrl =  | + |      $fileUrl = ($_GET['file']); | 
|      $referer = $_SERVER['HTTP_REFERER'] ?? ''; |      $referer = $_SERVER['HTTP_REFERER'] ?? ''; | ||
2025年10月31日 (金) 02:47時点における版
この例は、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
- >PHP7.4
 
- proxyへのアクセスに際して、refererリクエストヘッダが必要なコードになっています。
<?php
// 許可するリファラードメインの正規表現リスト
// 必要に応じてここにドメインを編集・追加してください。
$allowedReferers = [
    '#^https?://www\.svgmap\.org/#',
    // '#^https?://example\.com/#',
];
if (isset($_GET['file'])) {
    $fileUrl = ($_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>";
}
