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

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

ただいまの
回答率

90.52%

  • JavaScript

    16365questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • HTML

    8940questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • Node.js

    1856questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

  • Ajax

    1090questions

    Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

  • Express

    242questions

    ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。

Ajax通信でページ移動ができない(サーバーサイドにExpress.js使用)

解決済

回答 2

投稿 編集

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

nullpurge

score 18

 前提

サーバーサイドはNode.jsで、フレームワークにExpressを使用しています。

 現状

htmlのinputタグにおけるフォーム送信は正常に受理され、ページ移動するのですが、Ajax通信で同じことをすると、ログイン認証は通過しているものの結果的にページ移動さえされません。

まず、そもそもページ移動の際、サーバーから送られてきたhtmlファイルのデータをクライアントがどのように表示させているのかという知識がないので、解決する術がみあたらず結局ここに質問させていただきました(´;ω;`)

 ファイル構成

testApp
│
│  app.js
│  package-lock.json
│  package.json
│
├─bin
│      www
│
├─node_modules
│  
├─public
│  ├─css
│  │      login.css
│  │
│  └─js
│          login.js
│
├─routes
│      login.js
│      myPage.js
│
└─views
        error.pug
        layout.pug
        login.pug
        myPage.pug

 該当のソースコード

※全てのソースコードのZIPは最下部にリンクを張っています

/public/js/login.js(クライアントサイド)↓

window.onload = function(){

    //入力省略
    $("input[name='username']").val('user');
    $("input[name='password']").val('pass');


    //Ajax通信
    $('#submitButton2').on('click', function(){
        console.log($('#loginForm').serializeArray());
        $.ajax({
            type: 'POST',
            url: '/myPage',
            data: $('#loginForm').serializeArray()
        });

    });

};

/views/login.pug(クライアントサイドのページ)↓

doctype html
html(lang='ja')
    head
        title= title
        link(href='/css/login.css', rel='stylesheet')
        script(src='http://code.jquery.com/jquery-3.3.1.js' integrity='sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=' crossorigin='anonymous')
        script(src='/js/login.js', type='text/javascript')
    body
        form(method='POST' action='/myPage')#loginForm
            .itemBlock
                .formLabel ユーザー名
                input(type='text' name='username')
            .itemBlock
                .formLabel パスワード
                input(type='password' name='password')
            .btnBlock
                input(type='submit' value='INPUTタグによる送信')#submitButton1.sb
                #submitButton2.sb Ajaxによる送信

app.js(サーバーサイド)↓

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var login = require('./routes/login');
var myPage = require('./routes/myPage');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/'      , login );
app.use('/login' , login );
app.use('/myPage', myPage);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

/routes/myPage.js(サーバーサイド)↓

var express = require('express');
var router = express.Router();

/* GET users listing. */
router.get('/', function(req, res, next) {
    res.redirect('/login');
});

/* POST users listing. */
router.post('/', function(req, res) {

    var data = req.body;
    var {username, password} = data;

    console.log(data);

    if(username === 'user' && password === 'pass'){
        res.render('myPage');
        console.log('ログイン成功(*´ω`)');
    }
    else{
        res.redirect('/login');
        console.log('ログイン失敗(´・ω・`)');
    }

});

module.exports = router;

ソース

全体のソースコードです
https://mega.nz/#!DmZXVYZL

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • HayatoKamono

    2018/04/25 16:54

    > 今回の質問はhtmlのフォーム送信のようなブラウザの動作を、ajaxだけでどのようにすれば実装できるのだろうという知的欲求です。

    キャンセル

  • HayatoKamono

    2018/04/25 16:55

    ↑ すでにPostしたデータをサーバー側で取得が出来るいることは確認できているのですよね?であれば、すでに目的のことは達成できているのでは?

    キャンセル

  • nullpurge

    2018/04/25 17:01

    @HayatoKamono htmlにくっついているフォームのsubmit機能を実行するとpostでサーバーからhtmlドキュメント等を取得した上でurlが切り替わりレンダリングが行われるとおもうのですが(仕組みは理解できていませんが...)、それをajaxのcompleteプロパティ値となるコールバック関数で実装できないかと現在悩んでいます。

    キャンセル

回答 2

checkベストアンサー

+1

 回答の前提

修正依頼欄でもお伝えした通り、今回のようなケースではそもそも、ajax通信を行う必要はないかと思います。

その上で以下の回答は部分的に参考にして頂ければと思います。

また、以下のコードは質問文のコードをベースにしたコードにはなっていません。

 クライアントサイド

<button id='submitButton'>Submit</button>
$(document).ready(function() {

  var $submitButton = $('#submitButton');

  $submitButton.on('click', handleSubmit);

  function handleSubmit(event) {

    $.ajax({
      type: 'POST',
      url: 'https://jsonplaceholder.typicode.com/posts',
      data: JSON.stringify({ title: 'foo', body: 'bar', userId: 1 }),
      dataType: 'json',
      contentType: 'application/json'
    })
      .done(function(data) {
        console.log(data);
        location.href = 'https://codepen.io/';
    })
      .error(function(error) {
        console.log(error)
    })

  }


});

https://codepen.io/anon/pen/Vxjjwb

こちらのコードではjsonplaceholder.typicode.comというデモのAPIを公開してくれているサイトにpostリクエストを送って、postが成功して結果が返ってきたら、他のページへ遷移させるというコードになります。

冒頭に記載したとおり、ajaxでリクエストを投げて、結果が返ってきたら他のurlを表示させるということ自体が一般的にはあまり行われないので、単純にここでは、location.hrefの値を変えると、他のページをブラウザーがロードしてくれるのだということだけを読み取って参考にして下さい。

 サーバーサイド

When the parameter is an Array or Object, Express responds with the JSON 
representation:

https://expressjs.com/en/4x/api.html#res

res.send({ user: 'tobi' });

一般的にはajax通信でサーバー側からクライアント側に返すデータ形式はjson`形式であることが多いかと思います。
res.send()object{}array[]を渡して、クライアント側にjsonデータを返すようにしてください。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/04/25 18:56

    私の思い描いていた理想では、
    ① ajaxでサーバーへpostでリクエストを出す
    ② postで送られたデータがOKだったら、サーバーがマイページ(制限されたページ)のhtmlデータを返す
    ③ クライアントが返されたデータを用いページ移動(url変更とレンダリング)
    というのを思い浮かべていたのですが、

    HayatoKamono様のコードをみてみると、どこかのURLにPOSTでデータを送信して、なにかしら返ってきたら、それとは別のURLにアクセスする(GETで)というものに思えてしまいます。

    おそらく何か勘違いが生じていらっしゃるかもしれません...

    キャンセル

  • 2018/04/25 21:35

    まず、前提として質問修正依頼の方でお伝えしたとおり、今回やっていること自体がおかしなことをしているので、あまり自分の回答自体が参考になるようなものではないです。部分的に参考にして頂ければと思っています。ちょっと回答に補足を加えますね。その後に頂いた質問に回答します。

    キャンセル

  • 2018/04/25 21:56 編集

    > 私の思い描いていた理想では、
    > ① ajaxでサーバーへpostでリクエストを出す
    > ② postで送られたデータがOKだったら、サーバーがマイページ(制限されたページ)のhtmlデータを返す
    > ③ クライアントが返されたデータを用いページ移動(url変更とレンダリング)
    というのを思い浮かべていたのですが、

    修正依頼欄の最初のコメントでも「とは言え、今のやり方にもおかしな部分がありますが」と、少し触れましたが、質問文に掲載されているコードはおかしいです。

    一旦、ajaxを抜きにするとして、やりたいこととしては以下ではないでしょうか?

    A. loginページにアクセスしてきたユーザーにloginページを表示。(GET)

    B. loginページから送信されたログイン情報をチェック(POST)
    ---- b1. ログイン情報が正しければ、ユーザーをmypageにリダイレクト(GET)
    ---- b2. ログイン情報に誤りがあれば、エラー表示をしたloginページを表示(GET)

    C. ログイン認証をパスしたユーザーにmypageを表示(GET)

    D. ログイン状態ではないユーザーがmypageにアクセスしてきたら、loginページへリダイレクト

    上の箇条書きをベースにすると、質問文に掲載されているコードの場合、loginページにpostするとloginページでmypageのコンテンツをloginページのurlで表示するといったようなことをしていると思います。

    一旦、ajaxのことは脇において、ご自身の質問文に掲載しているコードを見直してみると良いかもしれません。

    キャンセル

  • 2018/04/25 22:04

    な、なるほど.....。
    POSTで認証を判別し、サーバー側で控えておき、GETでアクセスさせてそこで判別させるんですね。
    なんでその発想が浮かばなかったんだろう・・・。

    おそれいりました₍._.₎
    時間を割いていただきありがとうございました。

    キャンセル

+1

ajax通信後に画面遷移する記述がないため遷移しないのだと思います。
ajaxは、クライアントから非同期で必要なデータをサーバに送り、
サーバーサイドで処理し、クライアントに整形済データを返す、ものなので
帰ってきたデータを使い、クライアント側での処理を記載しない限り、
クライアント側には通常なにも反映されません。

ajax通信の返り値をみてから画面遷移の処理を記載してはいかがでしょうか。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/04/25 16:54

    ありがとうございます!
    画面遷移の処理の方法を調べてみます。

    キャンセル

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

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

関連した質問

同じタグがついた質問を見る

  • JavaScript

    16365questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • HTML

    8940questions

    HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

  • Node.js

    1856questions

    Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

  • Ajax

    1090questions

    Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

  • Express

    242questions

    ExpressはNode.jsのWebアプリケーションフレームワークです。 マルチページを構築するための機能セットおよびハイブリッドのWebアプリケーションを提供します。