29
42

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

クロスドメインでめちゃくちゃハマった話

Last updated at Posted at 2018-07-15

Ajaxは奥が深い。仕事でWEBアプリ開発する中で、クロスドメインで苦労したので忘備録として記録しておく。

#1.Ajaxとは?
まずはAjax。実は、今までAjaxをそこまで理解していなかった。(同期通信でデータ取ってくる業務システム開発ばかりだったこともあるかも。)jqueryで書くと簡単ですね。

【Ajax】
① Asynchronous Javascript + XML の略。
② ページを遷移することなく、動的にページの一部を置き換えることが可能な技術

サンプル描いて見ました。
jqueryで書くと簡単なんですが、今回はあえてNativeで。

   <script>
        window.onload = function () {
            var xhr = new XMLHttpRequest();
            xhr.addEventListener('loadend', function () {
                if (xhr.status === 200) {
                    console.log(xhr.response);
                } else {
                    console.error(xhr.status + ' ' + xhr.statusText);
                }
            });
            xhr.open('GET', 'http://localhost:3000/api/test/');
            xhr.send(null);
        }
   </script> 

XMLHttpRequestは、*「HTTPプロトコルを使用して通信し、テキスト形式やXML形式のデータを送受信するオブジェクト」*普段はjqueryで書いちゃっているけど、内部的に何をやっているかは実際に書いてみないとわかんないし、実際のリファレンス見るの大事ですね。

《参考》XMLHttpRequest - Web API インターフェイス | MDN
https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest

#2.クロスドメイン制約とは?
簡単なサンプルを作ってみました。構成はこんな感じ。

【フロント】
HTML5 + JavascriptでAjaxを実装。後述の簡易APIサーバーにGETリクエスト
を送っています。


<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Page Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <script>
        window.onload = function () {
            // HTTPプロトコルを使用して通信し、テキスト形式やXML形式のデータを送受信するオブジェクト
            var xhr = new XMLHttpRequest();
            xhr.addEventListener('loadend', function () {
                if (xhr.status === 200) {
                    console.log(xhr.response);
                } else {
                    console.error(xhr.status + ' ' + xhr.statusText);
                }
            });
            xhr.open('GET', 'http://localhost:3000/api/test/');
            xhr.send(null);
        }
    </script>
</body>
</html>

【サーバーサイド】

《参考》サルでも分かるExpressでのjsonAPIサーバーの作り方
https://qiita.com/leafia78/items/73cc7160d002a4989416

Node.js とExpressで簡易APIサーバーを作成。特にDBとかは用意してません。
URLにアクセスしたら、jsonを返すだけの簡単なコード。ほぼ参考リンクのサンプル通りです。

api
 ┣ app.js
 ┣ package.json

// ライブラリ読み込み
var express    = require('express');
var app        = express();
var bodyParser = require('body-parser');

//body-parserの設定
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

var port = process.env.PORT || 3000; // port番号を指定

// GET http://localhost:3000/api/test/
app.get('/api/test/',function(req,res){
    res.json({
        message:"Hello,world"
    });
});

//サーバ起動
app.listen(port);
console.log('listen on port ' + port);

htmlをブラウザで開いた瞬間にAjaxが実行されるようになっているので、
本来ならばapiの結果が返ってくるはずなんですが。このようなエラーが。

No 'Access-Control-Allow-Origin' header.png

何だろ?と思って調べると、XMLHttpRequestの呼び出しは、同一ドメインからしかできないようになっているとのこと。フロントエンドとバックエンドを異なるアプリケーションでデバッグする場合、同一のポート番号は使用できないため、異なるoriginと認識され、エラーとなってしまいました。

※クロスオリジンの制約は、ブラウザのアドレスバーに表示される URL と JavascriptからアクセスさるURLを比べて、プロトコル、ドメイン、ポート のどれかが違えば別のオリジンということになるそうです。ドメインが同じでも片方だけ https だったり、ポート番号が違う場合は別のオリジンと判断されるみたい。

参考サイトをたくさん貼っておきます。

《参考》

【解説付き】chromeでXMLHttpRequestをローカルのファイルで行う方法
https://qiita.com/growsic/items/a919a7e2a665557d9cf4

クロスドメインアクセスを理解してWeb APIを楽しく使おう - SlideShare
https://www.slideshare.net/kitfactory/web-api-34814937

これを知らなくて、ドメイン違いのAjax通信を実装してしまって苦労しました。。

29
42
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
29
42

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?