LoginSignup
1
0

More than 1 year has passed since last update.

【Java】簡単なSpringソースコードでJSONPの有効性を確認する

Last updated at Posted at 2023-02-18

【概要】

SpringでJSON形式の固定文言を返却するWeb APIを作成します。
作成したWeb APIをブラウザから非同期処理で呼び出し、JSONPの有効性を確認します。
確認するパターンとしては下記4通りで、一番右のWeb API呼び出し結果の列にはパターンごとの実行結果を記載しています。

パターンNo 同一オリジンである JSONPを使用する Web API呼び出し結果
1 Yes Yes 正常
2 Yes No 正常
3 No Yes 正常
4 No No エラー

【環境】

Java11
Google Chrome

【構成イメージ】

ポート番号のみを変更したサーバを2台用意します。
サーバに用意されているWeb API(Javaソース)は、ほぼ同一です。
ブラウザには同一オリジンであるSame-Originサーバのhtmlを表示し、そのhtmlに用意されたボタンをクリックすることでWeb APIを呼び出します。

構成イメージ.png

【コード】

GitHubにアップロードしてあります。

Javaソースは、JSON形式の固定文言を返却するWeb APIです。
htmlソースは、Web APIを呼び出すための画面です。
ボタンをクリックすることにより非同期処理でWeb APIを呼び出し、呼び出し結果をダイアログで表示します。

ソースコード一部抜粋

javaソースはWeb APIのメイン処理を抜粋しています。

    public String execute(@RequestParam(required = false) String callback, HttpServletResponse response) {
		// JSON形式の固定文言
		String json = "{ \"name\": \"suzuki\", \"age\": \"30\" }";
		
//		パターン4の回避用
//		response.setHeader("Access-Control-Allow-Origin", "http://localhost:50001");

		// JSONPを使用する場合
		if (callback != null) {
			// JSONP用
			return callback + "(" + json + ")";
		}
		return json;
    }

index.htmlはsameorigin-apiプロジェクトのみにあります。

index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<script>
	function getJson(jsonUrl) {
		$.ajax({
			url: jsonUrl,
			dataType: 'json'
		}).done(function (json) {
			alert(JSON.stringify(json));
		}).fail(function () {
			alert('getJson failed');
		});
	}
	
	function getJsonp(jsonUrl) {
		$.ajax({
			url: jsonUrl,
			dataType: 'jsonp',
			jsonpCallback: 'test',
		}).done(function (json) {
			alert(JSON.stringify(json));
		}).fail(function () {
			alert('getJsonp failed');
		});
	}
</script>
</head>
<body>
<button onclick="getJsonp('http://localhost:50001/sameorigin/api?callback=test')">パターン1 Same-Origin かつ JSONP使用</button>
<br><br>
<button onclick="getJson('http://localhost:50001/sameorigin/api')">パターン2 Same-Origin かつ JSONP不使用</button>
<br><br>
<button onclick="getJsonp('http://localhost:50002/crossorigin/api?callback=test')">パターン3 Cross-Origin かつ JSONP使用</button>
<br><br>
<button onclick="getJson('http://localhost:50002/crossorigin/api')">パターン4 Cross-Origin かつ JSONP不使用</button>
</body>
</html>

【実行準備】

Eclipseにプロジェクトをmavenプロジェクトとしてインポートし、pom.xmlをインストール実行します。
その後、それぞれのプロジェクトをSpring Bootアプリケーションで起動し、以下のURLへアクセスします。
http://localhost:50001
実行準備.png

【実行結果】

パターン1~4までのボタンをクリックした時の実行結果は下記通りとなります。
パターン1~3までの実行結果はいずれも同じです。

パターン1~3

Web API呼び出し結果は正常のため、JSON形式の固定文言が出力されます。
パターン1~3.png

パターン4

Web API呼び出し結果はエラーのため、JSON形式の固定文言が出力されずエラーメッセージが出力されます。
エラーとなった原因は同一オリジンではないサイトに対して、JSONPを使用していないためです。
パターン4.png

開発者ツールのコンソールタブを開くと下記エラーメッセージが出力されていることが確認できます。
ただ、エラーメッセージはJSONPが使われていませんという説明ではなく、レスポンスヘッダにAccess-Control-Allow-Originヘッダがありませんという説明になります。
cross-origin_json_error.png

CORSポリシーのエラー文を抜粋したのが下記文言です。

Access to XMLHttpRequest at 'http://localhost:50002/crossorigin/api' from origin 'http://localhost:50001' 
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

このエラー文で説明された通り、JavaソースにAccess-Control-Allow-Originヘッダを追加すればエラーが解消し、パターン1~3と同じ結果となります。

-//		response.setHeader("Access-Control-Allow-Origin", "http://localhost:50001");
+		response.setHeader("Access-Control-Allow-Origin", "http://localhost:50001");
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0