前提
サーバーサイドは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ページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
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
データを返すようにしてください。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
+1
ajax通信後に画面遷移する記述がないため遷移しないのだと思います。
ajaxは、クライアントから非同期で必要なデータをサーバに送り、
サーバーサイドで処理し、クライアントに整形済データを返す、ものなので
帰ってきたデータを使い、クライアント側での処理を記載しない限り、
クライアント側には通常なにも反映されません。
ajax通信の返り値をみてから画面遷移の処理を記載してはいかがでしょうか。
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.31%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
質問への追記・修正、ベストアンサー選択の依頼
Lulucom
2018/04/25 00:30
「ログインができない」というより「ページ遷移できない(やり方がわからない)」ということでしょうか?
nullpurge
2018/04/25 00:33
そうです!まさに
Lulucom
2018/04/25 00:36
ではそのように修正された方が回答が付きやすいかと思います。
HayatoKamono
2018/04/25 13:01 編集
ajaxを利用する場合、何らかの目的のためにブラウザーをフルリロードさせたくないから利用するというケースが大半かと思いますが、何故、非同期でサーバー側と通信を行い、そして、別ページへ遷移させたいのでしょうか?サンプルコードを見る限り、非同期でやるより、今のやり方の方が好ましいように感じますが。 (とは言え、今のやり方にもおかしな部分がありますが)
nullpurge
2018/04/25 16:53
@HayatoKamotno ぐぬぬ...。そういわれてしまうと自分はすごく滑稽なことをしてるのかも・・・。そうですよね、元々ajax通信は部分的にDOMデータを更新する用途ですものね。元々別の目的にajaxを使用しようとしていて、そこから派生して今回の疑問にたどり解いたという感じです。今回の質問はhtmlのフォーム送信のようなブラウザの動作を、ajaxだけでどのようにすれば実装できるのだろうという知的欲求です。
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プロパティ値となるコールバック関数で実装できないかと現在悩んでいます。