質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Azure

Azureは、マイクロソフトのクラウド プラットフォームで、旧称は Windows Azureです。PaaSとIaaSを組み合わせることで、 コンピューティング・ストレージ・データ・ネットワーキング・アプリケーションなど多くの機能を持ちます。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

Q&A

解決済

1回答

2399閲覧

【C# AppService】ブラウザからWebページをAPIのように中継サーバ経由で取得がしたい

sumpay

総合スコア5

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Azure

Azureは、マイクロソフトのクラウド プラットフォームで、旧称は Windows Azureです。PaaSとIaaSを組み合わせることで、 コンピューティング・ストレージ・データ・ネットワーキング・アプリケーションなど多くの機能を持ちます。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

0グッド

1クリップ

投稿2020/03/20 05:28

編集2020/03/21 00:15

前提

現在、クライアントPCのブラウザからAzure AppServiceを経由してIPアドレス制限がかかっているAPIにアクセスし、情報を取得するプログラムを実装済みで運用しております。

セキュリティの関係でクライアントから直接はAPIアクセスを禁じていて、.NetFramework4.6.1のC#で構築しているAPIのIPアドレスからのみ接続を許可している状況です。
利用イメージとして、クライアントPCブラウザからクエリ文字列でhttps://localhost/api/translate にアクセスしてもらい、取得したパラメータをhttp://XXX.jp/api/translate/へGETでアクセスして、戻り値をjson形式で
クライアントに戻す形になります。

C#

1public class TranslateController : ApiController 2 { 3 [HttpPost] 4 public HttpResponseMessage Get([FromUri]Maps value) 5 { 6 Translate tran = new Translate(); 7 8 tran.Client_id = value.Client_id; 9 tran.Text = value.Text; 10 tran.From_lang = value.From_lang; 11 tran.To_lang = value.To_lang; 12 13 //文字コードを指定する 14 Encoding encoding = System.Text.Encoding.GetEncoding("utf-8"); 15 16 string uri = "http://XXX.jp/api/translate/"; 17 18 uri = String.Concat(uri, "? "&text=", tran.Text, "&from_lang=", tran.From_lang, "&to_lang=", tran.To_lang); 19 20 //WebRequestの作成 21 System.Net.WebRequest req = System.Net.WebRequest.Create(uri); 22 23 req.Method = "GET"; 24 25 //サーバーからの応答を受信するためのWebResponseを取得 26 System.Net.WebResponse res = req.GetResponse(); 27 System.IO.Stream resStream = res.GetResponseStream(); 28 System.IO.StreamReader sr = new System.IO.StreamReader(resStream, encoding); 29 30 string responseBody = sr.ReadToEnd(); 31 sr.Close(); 32 33 TransrateResponseMessage transrateResponseMessage = JsonConvert.DeserializeObject<TransrateResponseMessage>(responseBody); 34 35 string result = AISignage.ResponseJsonSerializer.Serialize(transrateResponseMessage); 36 37 HttpResponseMessage resMsg = new HttpResponseMessage(HttpStatusCode.OK); 38 StringContent sc = new StringContent(result, System.Text.Encoding.GetEncoding("UTF-8"), "application/json"); 39 40 resMsg.Content = sc; 41 42 return resMsg; 43 } 44 }

こちらのプログラムに追加機能として、、このような形でクライアント → API → IPアドレス制限がかかっているWebページを表示させたいと思っています。
まず、練習でGoogleMapのページを表示するように下を作成しました。(特に変数等は入力しないで直打ちURLのアクセスです)
しかし、GoogleChromeでhttps://localhost/api/Maps にアクセスしたところ、空白のページが表示されるだけでした。

C#

1 public class MapsController : ApiController 2 { 3 [HttpGet] 4 public HttpResponseMessage Get([FromUri]Maps value) 5 { 6 7 Maps map = new Maps(); 8 map.lat = value.lat; 9 map.lon = value.lon; 10 11 //文字コードを指定する 12   Encoding encoding = System.Text.Encoding.GetEncoding("utf-8"); 13       //練習 14 uri = "https://www.google.com/maps/place/%E6%9D%B1%E4%BA%AC%E9%83%BD%E5%BA%81/@35.6916588,139.6949166,14.73z/data=!4m5!3m4!1s0x60188cd4b71a37a1:0xf1665c37f38661e8!8m2!3d35.6896355!4d139.6921009?hl=ja"; 15 16 17 18 ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; 19 20 WebClient wc = new WebClient(); 21 try 22 { 23 wc.Encoding = Encoding.UTF8; 24 string text = wc.DownloadString(uri); 25 HttpResponseMessage resMsg = new HttpResponseMessage(HttpStatusCode.OK); 26 StringContent sc = new StringContent(text, System.Text.Encoding.GetEncoding("UTF-8"), "text/html"); 27 resMsg.Content = sc; 28 29 return resMsg; 30 31 } 32 catch (WebException exc) 33 { 34 //失敗した際は空欄を返す 35 HttpResponseMessage resMsg = new HttpResponseMessage(HttpStatusCode.OK); 36 StringContent sc = new StringContent("", System.Text.Encoding.GetEncoding("UTF-8"), "text/html"); 37 38 resMsg.Content = sc; 39 40 return resMsg; 41 } 42 43 44 } 45 }

発生している問題・エラーメッセージ

ブラウザからhttps://localhost/api/Mapでアクセスしても、本来表示させたい東京都庁のMAPが表示されない

URL

1https://www.google.com/maps/place/%E6%9D%B1%E4%BA%AC%E9%83%BD%E5%BA%81/@35.6916588,139.6949166,14.73z/data=!4m5!3m4!1s0x60188cd4b71a37a1:0xf1665c37f38661e8!8m2!3d35.6896355!4d139.6921009?hl=ja

開発者ツールで確認したところ、GoogleMapにアクセスした際に実行されるScriptファイルなどがhttp://localhost/になっているため、404で表示されないのが原因というところまでは確認できました。(相対パスで指定されているScriptファイルが取得できない)

URL

1//直接接続した場合のURL 2https://www.google.com/maps/_/js/k=maps.m.ja.7rVG_8q465Y.O/m=sc2,per,mo,lp,ep,ti,ds,stx,pwd,ppl,log,std,b/rt=j/d=1/rs=ACT90oHl_nLra75AA7H-xA8ZqMSs533aUg 3//サーバ経由で接続した場合のURL 4http://localhost/maps/_/js/k=maps.m.ja.7rVG_8q465Y.O/m=sc2,per,mo,lp,ep,ti,ds,stx,pwd,ppl,log,std,b/rt=j/d=1/rs=ACT90oHl_nLra75AA7H-xA8ZqMSs533aUg

実現したいこと

本来はリバースプロキシなどを用意して実現するべきことだとは思っておりますが、
別途IaaSを用意することが難しいことと、IPアドレス許可の追加に時間がかかるため、
できればすでにIPアドレスが許可されているAppService上で実現できないかと考えております。

恐れ入りますが、なにか対応方法についてご教授いただけますでしょうか。

補足情報(FW/ツールのバージョンなど)

.Netframework 4.6.1

Microsoft VisualStudio 2017 Ver15.9.6

### 構成イメージの追加 0320
イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/03/20 10:02

全体の構成がどうなっているか、パッと見分かるような情報を提供していただけませんか? クライアント(ブラウザ)⇔ Azure(ASP.NET Web アプリ?)⇔ どこか他の Web API ・・・ということなのでしょうか? 分からないです。
sumpay

2020/03/20 11:05

コメントありがとうございます。構成イメージを追記いたしました。 現在の構成(TransrateのAPI利用)はご指摘頂いたとおりです。 クライアント(ブラウザ)⇔ Azure(ASP.NET WebAPI)⇔ 他社が公開しているWeb API この構成に、イメージ下段のWEBページとして提供されているMAPサービスを呼び出す仕組みを追加したいと考えております。
hoshi-takanori

2020/03/20 22:21

普通の web proxy では駄目なのでしょうか?
sumpay

2020/03/20 23:03

コメントありがとうございます。 >普通の web proxy では駄目なのでしょうか? クライアントPC側にプロキシの設定を入れることは運用の関係で不可能なため、 WebProxyを用いた対応以外の解決法を必要としております。
退会済みユーザー

退会済みユーザー

2020/03/20 23:28

ASP.NET のタグを付けていただくようお願いします。 とりあえず練習で、開発マシンで IIS Express 上で動かしている ASP.NET Web API に、開発マシンのブラウザからアクセスして、Web API 経由で google から情報を取得できれば、その先は自己解決できるということで良いのでしょうか? (本番環境は第三者には検証できないようなので、何ともならないかと) google の API は仕様が公開されているのでしょうか? それが分かる url を教えて下さい。
sumpay

2020/03/20 23:40

私の記載の方法がわかりにくく、申し訳ありません。 >google の API は仕様が公開されているのでしょうか? それが分かる url を教えて下さい。 例でGoogleMAPを上げてましたが、これはAPIを利用しているのではなく普通のWebページを表示したいだけになります。  例えばhttp://www.dmm.com/netgame/feature/kancolle.htmlでもいいのですが、jsファイルなどがWebAPI経由で正常に読み取ることができればその後は自己解決できると考えております。
退会済みユーザー

退会済みユーザー

2020/03/20 23:57 編集

読み直してみると、google のケースでは、応答として返ってくるのは html ページで (本番環境で使う json ではなく)、その html ページで外部スクリプトファイルへの参照が相対 url なっているからうまくいかないと言うことのようですね。そうだとすると、それは当たり前で、その解決策を考えるのは時間の無駄と思います。練習に使った相手が間違っているかと。 練習用には、自分で開発環境に json を返すアプリを作って、それに Web API からアクセスすることはできませんか?
退会済みユーザー

退会済みユーザー

2020/03/21 00:07

クライアントがブラウザということですので、中継するのに使うのはホントに Web API が適切かも考え直した方が良さそうな気がします。(ASP.NET MVC の方が適切かも)
sumpay

2020/03/21 00:12

改めて自分の質問文を読み直してみたところ、勘違いされるような記載になっておりましたので修正しました。 まずクライアント → WebAPI → 外部APIのjsonファイル取得は作成して問題なく動いております。 次段階の機能として同じ形式で、 クライアント → WebAPI → html ページを取得したかったのです。 >google のケースでは、応答として返ってくるのは html ページで (本番環境で使う json ではなく)、 >その html ページで外部スクリプトファイルへの参照が相対 url なっているからうまくいかないと言うことのようですね。そうだとすると、それは当たり前で、その解決策を考えるのは時間の無駄と思います。 これの解決法を質問したかったのですが、このように記載いただきましたので別の方法で検討する必要がありそうですね。コメントいただきありがとうございます。
hoshi-takanori

2020/03/21 00:30

WebAPI と書くと別のものを想像するので、独自中継サーバーと呼ぶのがいい気がします。 他の言葉の使い方を見ても、全体的にネットワーク技術の理解が足りてないのでは…。 また、セキュリティのために Web アクセスを塞いでいるのなら、独自中継サーバーを立てて Web アクセスをトンネリングするなんてのは一番やっちゃいけないことのはずで、目的の Web サイト以外にはアクセスできないような手段を構築するのがネットワーク管理者の仕事です。(理想論ですが。)
退会済みユーザー

退会済みユーザー

2020/03/21 00:59 編集

自分が思い付く方法は、ブラウザに送信する前に Web API の中で正規表現を使って相対 url を絶対 url に書き換えるぐらいですが、サイトルート相対パスならともかくページからの相対パスが使われていると、不可能とまでは言えませんがかなり無理っぽいです。 スクリプトファイルだけでなく、画像、css ファイルもあるでしょうし。取得した外部スクリプトを使ってさらに外部 url から情報を取得しているかもしれませんませんし。そう言う場合は限りなく不可能に近いと思います。 プロキシを使うなど正攻法で行くべきかと。
guest

回答1

0

ベストアンサー

いろいろ誤解してましたが、以下のような話ですよね。

(1) 現状は以下の通りで、「他社が公開しているWeb API」から JSON 文字列を取得しており、これは問題なく運用できている。

クライアント(ブラウザ)⇔ Azure(ASP.NET WebAPI)⇔ 他社が公開しているWeb API

(2) 次のステップとして、「他社が公開しているWeb API」を html を返す一般的な Web サイト(例えばここ Teratail のようなサイト)にし、「Azure(ASP.NET WebAPI)」を中継して「クライアント(ブラウザ)」に表示したい。

クライアント(ブラウザ)⇔ Azure(ASP.NET WebAPI)⇔ 一般的な Web サイト

(3) その練習として、「一般的な Web サイト」を Google Map にして試してみた。

(4) ところが、クライアントに返ってくる html ソースは、外部スクリプトファイルなどへの参照が相対パスを使って書かれているため、クライアントからその外部スクリプトファイルを要求するときは「Azure(ASP.NET WebAPI)」に要求が出るため 404 Not Found となる。

(5) これを何とかする方法はないか検討中。

・・・ということで、(5) がこのスレッドの質問であるとやっと理解できました。

その理解が正しければ、私の回答は、質問のコメント欄にも書きましたが、「プロキシを使うなど正攻法で行くべき」です。

上に書いた構成で自分が思い付く方法は、ブラウザに送信する前に Web API の中で正規表現を使って相対 url を絶対 url に書き換えるぐらいですが、サイトルート相対パスならともかくページからの相対パスが使われていると、不可能とまでは言えませんがかなり無理っぽいです。

スクリプトファイルだけでなく、画像、css ファイルもあるでしょうし。取得した外部スクリプトを使ってさらに外部 url から情報を取得しているかもしれませんし。そう言う場合は限りなく不可能に近いと思います。

その限りなく不可能に近いことの解決に時間と労力を使うのと、正攻法で行くのを天秤にかければ、間違いなく後者が正解だと思います。

投稿2020/03/21 01:53

編集2020/03/21 01:57
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問