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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Node.js

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

Q&A

解決済

2回答

2432閲覧

koa-routerでリダイレクトせずにrouterを切り替えることはできますか?

hojo

総合スコア195

Node.js

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

1グッド

0クリップ

投稿2016/11/18 06:27

編集2016/11/18 06:45

nodejs + koaを利用してウェブサイトを作っています。

また、その環境の中でkoaのミドルウェアであるkoa-routerを利用してリクエストが発生したpathに対して処理を振り分けています。

その振り分けてある処理をリダイレクトせずにrouterに登録した他の関数に切り替えることはできますでしょうか?

つまり以下のようなことがしたいのですがどのようにすれば可能でしょうか?

const app = require('koa')() const router = require('koa-router')() router.get('/', function*(){ // this.redirect('/login') // 1.リダイレクトならうまくいくが使いたくない // this.path = '/login' // 2.これは期待した動作はしてくれない // this.body = 'this is login page.' // 3.これは期待した動作に近いが出力結果が同じだけで切り替わったわけではない this.jump('/login') // このようなことができれば嬉しいのだが... }) router.get('/login', function*(){ this.hoge = 1 this.body = 'this is login page.' }) app .use(router.routes()) .use(router.allowedMethods()) .listen(3000)

何故このようなことがしたいか、という経緯を念のため記載しておきます。

リダイレクトはブラウザのリクエスト先を変更するための強力な手法だが、リダイレクトを何も考えずに行うと、リクエストが無駄に発生してしまうためにサーバ負荷とユーザビリティ(レスポンス速度)の面で良い結果を生まない...

そこでリダイレクトを行わずにリダイレクト先の結果を返してあげればリダイレクトを行った時と同じような結果を得られるのではないか?と思い実際に試してみる。

その時は出力結果を変えるという手法をとり、routerに登録した関数を切り替えることはせずに、出力するHTMLを切り替えることで実現。(つまりコメントアウトの3番目)

しかし、この方法だと繊維先のページで必要としている処理を実行することはできない。具体的には/loginの方に記述されたthis.hoge = 1は実行されない...

this.jump()のようなメソッドがあれば実現できるのに...

経緯としては上記のような具合です。

また、リクエストがあったpathと表示結果が異なるため、リフレッシュをかけた時におかしなことになってしまうという問題が発生しそうですが、今はこの問題は気にしないでいただきたいです(histry.replaceStateでurl書き換えようと思っています。)

どうかよろしくお願いいたします。

matsu👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

#ウェブビュー相手のサーバー限定技ですね
リダイレクトを回避する手法は、運用面を考えて選択しましょう。
スマホ/タブレットなどのネイティブアプリ、あるいはRPCのような、人の手が介在しない運用環境に限定されます。

ウェブサイトにおいては、入力直後のリダイレクトにはこんな意味もあります。
「POSTされたデータを受理しました。その後のページに案内します」
「POSTでアクセスしています。GETでアクセスし直しなさい」

Perl製CGI(無料掲示板)が流行った頃、投稿直後のページ表示は禁じ手でした。
理由は「POST直後にF5キーを押されるとフォーム内容の再送信が行われ、二重投稿発生の原因になる」から。
今でこそ、ブラウザも警告を発しますが、「そんな警告を出すような実装にならないようにしたい」という当時の技術者の思いがあってリダイレクトで回避するのが定石となっています。

人が介在しやすいブラウザ相手の場合は、サーバー負荷とのトレードオフで得る「安心、安全」のほうが大きい。なので、運用環境がウェブサイトならやらないほうがいい手法です。
ご参考になればと思います。

投稿2019/10/20 13:13

AkitoshiManabe

総合スコア5432

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

自己解決

下記の実装で実現できました。

const app = require('koa')() const router = require('koa-router')() const _ = require('lodash') app.use(function*(next){ // jumpメソッドの実装 this.jump = (path, next)=>{ next = next || function*(){} let layer = _.find(router.stack, ['path', path]) _.eachRight(layer.stack, (v)=>next=v.call(this, next)) return next } yield next }) router.get('/', function*(){ yield this.jump('/login') }) router.get('/login', function*(){ this.hoge = 1 this.body = 'this is login page.' }) app .use(router.routes()) .use(router.allowedMethods()) .listen(3000)

投稿2016/11/19 03:12

編集2016/11/19 03:18
hojo

総合スコア195

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問