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

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

ただいまの
回答率

90.12%

ajaxでjsonを読み込もうとすると404 Not found Error が出てしまう

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 128

suzunox

score 31

問題

ajaxを使ってjsonファイルを読み込もうとしているのですが、404errorと出てしまいます。

ファイル群

ファイル構造は次のようになってます。

JSlaboratory
    app.py
    templates
        index.html
    static
        index.js
        data.json


app.pyの中身はこれです

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from flask import Flask, render_template

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

if __name__ == '__main__':
    app.run()


index.htmlの中身はこれです

<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>experience</title>
    </head>
    <body>
        <script src="http://code.jquery.com/jquery-3.2.1.min.js"></script>
        <script src="../static/index.js"></script>
    </body>
</html>


index.jsの中身はこれです

let A;
$.ajax({url: 'data.json', dataType: 'json'})
.done(function(data) {
    $(data).each(function(){
        A = this.id;
    })
})
.fail(function(){
    window.alert('error');
});
console.log(A);


data.jsonの中身はこれです

[
    {"id":"js","crowded":"yes"}
]


結果はerrorとアラートがでて、コンソールを見るとundefinedと404 not foundが出ています。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+2

$.ajax の url の指定が間違っていて、サーバー側で data.json が見つからないのが 404 エラーの原因で、結果 A が undefined になっているのではないかと思います。

試しに、data.json ファイルを index.html ファイルがあるフォルダにコピーしたらどうなりますか?

【追記】

注:以下は普通の web サーバー(具体的には Windows 10 Pro の IIS10)を使って、それにサイトを設定し、その中に index.html, data.json, index.js を配置した場合です。質問者さんは Flask を使ってその開発サーバーで実行しているとのことで、Flask 開発サーバーの制約で data.json, index.js を置くフォルダは static にする必要があるとのことです。(下の記事のように index.html, data.json を同一フォルダに置くのは NG のようです)

下の 2019/10/10 23:28 の私のコメントで「あとで回答欄に詳しい話を書いておきます」と書きましたが、それを以下に追記します。

templates フォルダの中に index.html と data.json を配置します。index.js は Script フォルダに入れておきます。以下の画像を見てください。

イメージ説明

index.html は jQuery ajax で取得した JSON データを表示するために<div id="result"></div>を追加した以外は質問者さんのコードと同じです。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>experience</title>
</head>
<body>
    <div id="result"></div>

    <script src="http://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script src="../Scripts/index.js"></script>    
</body>
</html>

質問者さんの index.js のコードは、上の index.html の<div id="result"></div>に JSON データを表示できるように done のコールバックを以下のように変更しました。 url: 'data.json' は変えてません。

index.js

$.ajax({ url: 'data.json', dataType: 'json' })
.done(function (data) {
    $.each(data, function (index, d) {
        $('#result').append(
            '<p>id: ' + d.id + ', crowded: ' + d.crowded + '</p>'
            );
    });
})
.fail(function () {
    window.alert('error');
});

index.html の実行結果は以下の通りとなり、期待通り JSON データが表示されます。もちろん 404 エラーなどは出ません。

イメージ説明

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/11 08:21

    僕は今高専2年生なんで、pythonの課題があったわけですよ。呼び出し方はapp.pyを起動するだけです。

    キャンセル

  • 2019/10/11 08:25

    でも、質問の仕方が悪かったのかなと思います。flaskを強調すればよかったのだと思います。迷惑をおかけしてすみませんでした。

    キャンセル

  • 2019/10/11 09:02

    自分は Flask は無知だったのでググって調べてみましたが、開発サーバーが実装されているようですね。

    コマンドで python app.py というように実行すると、開発サーバーが立ち上がって、http://localhost:5000/ でブラウザからの要求を受け付けるようになる。

    ブラウザから上記 url を要求すると、開発サーバーで質問者さんのコードの index() が実行され、index.html がブラウザに応答として返される。

    ・・・という仕組みになっているようです。

    開発サーバーの制約で、index.html が取り込む .js, .json ファイルは static フォルダに置いて、url を /static/data.json というようにサイトルート相対パスで指定する必要があったということと理解しました。

    理解が間違っていたらご指摘ください。

    キャンセル

+1

index.htmlとdata.jsonの相対位置(path)の問題では?
おなじディレクトリに置いてありますか?
data.jsonを公開ディレクトリのルートから絶対path指定してみてください
(最終的には相対pathに戻して構わないので)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

+1

JavaScript のカレントパスは、読み込まれている HTML が基準になります。
なので、../static/data.jsonなどになるのではないですか?

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

解決方法:
urlはapp.pyからの相対パスにする(Flaskを使っていたため)。url: static/data.json

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/10/10 23:28

    > templatesの中にdata.jsonを置いても404エラーが出てしまい

    templates フォルダの中に index.hhml と data.json はあれば、質問者さんのスクリプトが動くかどうかはともかく、少なくとも 404 エラーにはならないはず。やり方の問題だと思います。

    あとで回答欄に詳しい話を書いておきます。

    キャンセル

  • 2019/10/10 23:30

    すいません、何度もありがとうございます。

    キャンセル

  • 2019/10/11 10:14

    > urlはapp.pyからの相対パスにする(Flaskを使っていたため)。url: static/data.json

    「app.pyからの相対パス」と言うより、今回の質問者さんのコードでは「サイトルートからの相対パス」と言った方が当たっているのではないでしょうか?

    コマンドで python app.py というように実行すると、 Flask 開発サーバーが立ち上がって、app.py のコードの @app.route('/') に従って http://localhost:5000/ でブラウザからの要求を受け付けるようになり、開発サーバーが返す index.html はサイトルートにあるということになるはずです。

    なので、$.ajax に指定する url は /static/data.json というように static の前に / を入れてサイトルート相対パスと明示した方がよさそうな気がします。(結果は url: static/data.json でも同じでしょうけど)

    あと、index.html のコードの <script src="../static/index.js"></script> の src 属性も "/static/index.js" とした方がよさそうに思います。

    キャンセル

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

  • ただいまの回答率 90.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる