「クロスオリジンアクセス」の版間の差分

提供: svg2wiki
移動先: 案内検索
(概要)
(概要)
 
(同じ利用者による、間の8版が非表示)
2行目: 2行目:
  
 
== 概要 ==
 
== 概要 ==
SVGMapはハイパーレイヤリングアーキテクチャを持つため、[[解説書#フレームワークの呼び出し|ルートhtml文書]]で構成されるクライアントのSVGMapフレームワークウェブアプリは、異なるオリジンのサーバにアクセスすることが基本的に必要になります。これは一般的に「[https://developer.mozilla.org/ja/docs/Web/HTTP/CORS クロスオリジンリソース共有]」と呼ばれる処理が行われる可能性があり、この時[https://developer.mozilla.org/ja/docs/Web/HTTP/CORS/Errors ウェブブラウザのネイティブな機能によるCORSのエラー]が生じる可能性があることを意味します。
+
SVGMapはハイパーレイヤリングアーキテクチャを持つため、[[解説書#フレームワークの呼び出し|ルートhtml文書]]で構成されるクライアントのSVGMapフレームワークウェブアプリは、異なるオリジンのサーバにアクセスすることが基本的に必要になります。これは一般的に「[https://developer.mozilla.org/ja/docs/Web/HTTP/CORS クロスオリジンリソース共有](CORS)」と呼ばれる処理が行われる可能性があり、この時[https://developer.mozilla.org/ja/docs/Web/HTTP/CORS/Errors ウェブブラウザのネイティブな機能によるCORSのエラー]が生じる可能性があることを意味します。
  
 
クロスオリジンアクセスのケースと、CORSのエラー発生の可能性を下表に示します。
 
クロスオリジンアクセスのケースと、CORSのエラー発生の可能性を下表に示します。
  
 
{| class="wikitable" style="margin:auto"
 
{| class="wikitable" style="margin:auto"
|+ クロスオリジンアクセスによるエラー
+
|+ svgmapjsにおけるクロスオリジンアクセスによるエラー
 
|-
 
|-
 
! クロスオリジンアクセスするコンテンツの種類 !! コンテンツの処理 !! CORSエラー発生の可能性
 
! クロスオリジンアクセスするコンテンツの種類 !! コンテンツの処理 !! CORSエラー発生の可能性
13行目: 13行目:
 
| ビットイメージ(タイルを含む) || 重ね合わせ || 発生しない
 
| ビットイメージ(タイルを含む) || 重ね合わせ || 発生しない
 
|-
 
|-
| ビットイメージ(タイルを含む) || 非線形図法変換を伴う重ね合わせ || 発生する可能性あり
+
| ビットイメージ(タイルを含む) || [[#非線形図法変換|非線形図法変換]]を伴う重ね合わせ || 発生する可能性あり
 
|-
 
|-
 
| ビットイメージ(タイルを含む) || 地理空間情報処理等 || 発生する可能性あり
 
| ビットイメージ(タイルを含む) || 地理空間情報処理等 || 発生する可能性あり
21行目: 21行目:
 
| ベクトルデータやjson等ビットイメージ以外のデータ|| 地理空間情報処理等 || 発生する可能性あり
 
| ベクトルデータやjson等ビットイメージ以外のデータ|| 地理空間情報処理等 || 発生する可能性あり
 
|-
 
|-
| 全ての種類のコンテンツ・データ || [[解説書#svgMapCesiumWrapper..E3.81.A7.E5.91.BC.E3.81.B3.E5.87.BA.E3.81.9B.E3.82.8BAPI|Cesium拡張を用いた表示]] || 発生する可能性あり
+
| 全ての種類のコンテンツ・データ || [[解説書#svgMapCesiumWrapper..E3.81.A7.E5.91.BC.E3.81.B3.E5.87.BA.E3.81.9B.E3.82.8BAPI|Cesium拡張を用いた3D表示]] || 発生する可能性あり
 
|}
 
|}
  
70行目: 70行目:
 
<html>
 
<html>
 
...
 
...
<script src="corsProxy.js"></script> <!-- クロスオリジンアクセス用プロキシライブラリ(下記) -->
+
<script type="module">
<script src="SVGMapLv0.1_r17.js"></script>
+
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';
<script>
+
window.svgMap=svgMap
var proxyPath = "{セットアップしたCORS AnywhereのURL}"; // CORS anywhere for svgmap.org / service.svgmap.org
+
var corsProxy = new CorsProxy();
corsProxy.setService(proxyPath, null, true,false);
+
 
svgMap.setProxyURLFactory(null,null,null, corsProxy.getURL,true);
+
// プロキシの設定
 +
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>
 
</script>
 
...
 
...
84行目: 89行目:
  
  
====corsProxy.js====
+
====corsProxyMoule.js====
初期化を容易に行うためのライブラリをご紹介します。[https://github.com/svgmap/svgMapDemo/blob/main/js/corsProxy.js gitHub]
+
初期化を容易に行うためのライブラリをご紹介します。[https://github.com/svgmap/svgmapjs/blob/main/CorsProxyModule.js gitHub]
 
* corsProxy.setService(pxUrl , directURLls , useAnonProxy, requireEncoding)
 
* corsProxy.setService(pxUrl , directURLls , useAnonProxy, requireEncoding)
 
** pxUrl : プロキシのURL
 
** pxUrl : プロキシのURL
91行目: 96行目:
 
** useAnonProxy : anonymous属性を付与するかどうか
 
** useAnonProxy : anonymous属性を付与するかどうか
 
** requireEncoding : プロキシサービスに渡すURLをURLエンコードするかどうか
 
** requireEncoding : プロキシサービスに渡すURLをURLエンコードするかどうか
* corsProxy.getURL(プロキシに取得させるURL)
+
* corsProxy.getURLfunction : プロキシ経由のURLを得るための関数を得る
 
 
<code>
 
<pre>
 
var corsProxy = (function(){
 
var proxyUrl="";
 
var anonProxy = false;
 
var directURLlist = [];
 
var noEncode=true;
 
function setImageProxy( pxUrl , directURLls , useAnonProxy, requireEncoding){
 
if ( requireEncoding ){
 
noEncode = false;
 
}
 
proxyUrl = pxUrl;
 
if ( directURLls ){
 
directURLlist = directURLls;
 
} else {
 
directURLlist = [];
 
}
 
if ( pxUrl.indexOf("http")==0){
 
var pxDomain = pxUrl.substring(0,pxUrl.indexOf("/",8));
 
directURLlist.push(pxDomain);
 
}
 
 
if ( useAnonProxy ){
 
anonProxy = true;
 
} else {
 
anonProxy = false;
 
}
 
}
 
 
function isDirectURL(url){
 
// urlに、directURLlistが含まれていたら、true 含まれていなかったらfalse
 
var ans = false;
 
for ( var i = 0 ; i < directURLlist.length ; i++ ){
 
if ( url.indexOf(directURLlist[i])>=0){
 
ans = true;
 
break;
 
}
 
}
 
return ( ans );
 
}
 
 
function getImageURL(imageUrl){
 
// ローカル(同一ドメイン)コンテンツもしくはそれと見做せる(directURLlistにあるもの)もの以外をproxy経由のURLに変換する
 
// proxyの仕様は、 encodeURIComponent(imageUrl)でオリジナルのURLをエンコードしたものをURL末尾(もしくはクエリパート)につけたGETリクエストを受け付けるタイプ
 
if ( proxyUrl && imageUrl.indexOf("http") == 0){
 
if (isDirectURL(imageUrl)){
 
// Do nothing (Direct Connection)
 
} else {
 
if ( noEncode ){
 
imageUrl = proxyUrl + (imageUrl);
 
} else {
 
imageUrl = proxyUrl + encodeURIComponent(imageUrl);
 
}
 
// console.log("via proxy url:",imageUrl);
 
}
 
} else {
 
// Do nothing..
 
}
 
return (imageUrl);
 
}
 
return {
 
setService:setImageProxy,
 
getURL:getImageURL,
 
}
 
})();
 
</pre>
 
</code>
 
 
 
  
 
===webAppレイヤーでのクロスオリジンアクセス===
 
===webAppレイヤーでのクロスオリジンアクセス===
173行目: 109行目:
  
 
<code>var dataResponse = await fetch( "https://[myproxy.mydomain.com]/proxy/?targetURL=" + serviceURL );</code>
 
<code>var dataResponse = await fetch( "https://[myproxy.mydomain.com]/proxy/?targetURL=" + serviceURL );</code>
 +
 +
===非線形図法変換===
 +
メルカトル図法と正距円筒図法の間の図法変換など、1次アフィン変換(matrix(a,b,c,d,e,f))では変換できない座標変換を伴うもの

2025年1月23日 (木) 07:19時点における最新版

ビットイメージの地図レイヤーに図法変換が必要な場合や、XMLHttpRequestやfetchなどでwebappのあるサイトと異なるドメインにあるウェブサービス(webapi)にアクセスする場合、クロスオリジンアクセス制限によるエラーが起きる場合があります。このエラーはWebApp側だけでは解決できず、サーバ側の設定を調整する必要があります。

概要

SVGMapはハイパーレイヤリングアーキテクチャを持つため、ルートhtml文書で構成されるクライアントのSVGMapフレームワークウェブアプリは、異なるオリジンのサーバにアクセスすることが基本的に必要になります。これは一般的に「クロスオリジンリソース共有(CORS)」と呼ばれる処理が行われる可能性があり、この時ウェブブラウザのネイティブな機能によるCORSのエラーが生じる可能性があることを意味します。

クロスオリジンアクセスのケースと、CORSのエラー発生の可能性を下表に示します。

svgmapjsにおけるクロスオリジンアクセスによるエラー
クロスオリジンアクセスするコンテンツの種類 コンテンツの処理 CORSエラー発生の可能性
ビットイメージ(タイルを含む) 重ね合わせ 発生しない
ビットイメージ(タイルを含む) 非線形図法変換を伴う重ね合わせ 発生する可能性あり
ビットイメージ(タイルを含む) 地理空間情報処理等 発生する可能性あり
ベクトルデータやjson等ビットイメージ以外のデータ 重ね合わせ 発生する可能性あり
ベクトルデータやjson等ビットイメージ以外のデータ 地理空間情報処理等 発生する可能性あり
全ての種類のコンテンツ・データ Cesium拡張を用いた3D表示 発生する可能性あり

エラーの確認方法

ウェブブラウザでSVGMapのページを開き、開発ツールのコンソールもしくはネットワーク画面からエラーが確認できます。(blocked by CORS policyなどといったメッセージが出ます)

サーバ(サービス側での対処): CORSレスポンスヘッダを返すように設定する

  • Access-Control-Allow-Origin *(もしくは指定オリジン)のレスポンスヘッダを返すようにサーバを設定します。
  • 外部からのアクセスを想定し 整備されたサービスでは、この設定がされており(例:地理院地図やgitHubPagesのサイト) 下記プロキシの利用は不要です。

プロキシサービスを用意し これを経由させる

プロキシ経由のクロスオリジンアクセスを容易にするためのSVGMap.jsの支援機能

プロキシ経由のクロスオリジンアクセスの対応を容易にするためのいくつかの機能がSVGMap.jsに備わっています。

SVGMap.jsがクロスオリジンアクセスを必要とするケースは主に3つあります。

  1. ビットイメージ(含タイル)データの図法変換
  2. ラスターGIS
  3. webAppレイヤーでの独自の通信

1.と2.はSVGMap.jsの管理下でクロスオリジンアクセスを行う必要があるもので、SVGMap.jsの初期化時にクロスオリジンアクセスのための設定(クロスオリジンアクセスのためのプロキシの設定)を行うAPIが用意されています。

これらのAPIを用いた初期化の例は次章で説明します。

WebApp Layerにおけるクロスオリジンアクセス

一方、3.は各レイヤーのwebApp(webApp Layer)が、レイヤーのコンテンツを生成するためのデータ(例えばjson形式の独自データ)を取得するときに(fetchやXMLHttpRequest等を使い)クロスオリジンアクセスするケースで、厳密にはSVGMap.jsが関与しない処理です。このようなクロスオリジンアクセスに対するケアは、基本的に個々のレイヤーwebAppの開発者が行う必要があります。
しかしプロキシ経由のアクセスを行う場合、先の1.2.のケース用に使用するプロキシを全レイヤー共通のプロキシとしても利用する場合が考えられ、この時にはSVGMap.jsの初期化で設定したプロキシを共通の関数で呼び出せる関数が用意されています。

getCORSURLの使用法は後の章で紹介します。

SVGMap.jsの初期化

  • 先述の機能を用いて、容易にクロスオリジンアクセスを可能にするためのルートHTML文書の初期化手順を紹介します。corsProxy.jsは次章参照
    • ルートHTML文書の完全な実装例 : GitHub 

<!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>


corsProxyMoule.js

初期化を容易に行うためのライブラリをご紹介します。gitHub

  • corsProxy.setService(pxUrl , directURLls , useAnonProxy, requireEncoding)
    • pxUrl : プロキシのURL
    • directURLls : [プロキシを使用しないURLのリスト]
    • useAnonProxy : anonymous属性を付与するかどうか
    • requireEncoding : プロキシサービスに渡すURLをURLエンコードするかどうか
  • corsProxy.getURLfunction : プロキシ経由のURLを得るための関数を得る

webAppレイヤーでのクロスオリジンアクセス

クロスオリジンアクセスのためのSVGMap.jsの初期化がなされた状態のルートHTML文書(SVGMapページ)に登録されている各レイヤーのwebAppsでは、getCORSURL APIを使用することができます。

このAPIは、アクセスしたいサービスのURLに対して、共通で準備されたクロスオリジンアクセス用サーバを経由したアクセスを可能にするURLが得られる機能で、たとえば以下のように利用します。

var dataResponse = await fetch( svgMap.getCORSURL( serviceURL ) );


一方、もしクロスオリジンアクセスの初期化をしていないルートHTML文書(SVGMapページ)では、各レイヤーのwebAppsが独自にクロスオリジンアクセスの解決を行う必要があります。例えば、クロスオリジンアクセス用のプロキシとしてhttps://[myproxy.mydomain.com]/proxy/ というプロキシが用意されており、?targetURL=serviceURL というクエリパラメータでアクセス先のサービスにアクセスする場合は、以下のようになるでしょう。

var dataResponse = await fetch( "https://[myproxy.mydomain.com]/proxy/?targetURL=" + serviceURL );

非線形図法変換

メルカトル図法と正距円筒図法の間の図法変換など、1次アフィン変換(matrix(a,b,c,d,e,f))では変換できない座標変換を伴うもの