Express URL跳转(重定向)的实现方法


Posted in Javascript onApril 07, 2017

Express是一个基于Node.js实现的Web框架,其响应HTTP请求的response对象中有两个用于URL跳转方法res.location()和res.redirect(),使用它们可以实现URL的301或302重定向。

res.location(path)

res.location(path)

下面列举了几种,设置http响应头Location的方法

res.location('/foo/bar');
res.location('http://example.com');
res.location('back');

路径值back具有特殊的意义,这个涉及到请求头Referer中指定的URL,如果Referer头没有指定,将会设置为'/'。

Express通过Location头将指定的URL字符串传递给浏览器,它并不会对指定的字符串进行验证(除'back'外)。而浏览器则负责将当前URL重定义到响应头Location中指定的URL。

res.redirect([status,] path)

其中参数:

  1. status:{Number},表示要设置的HTTP状态码
  2. path:{String},要设置到Location头中的URL

使用指定的http状态码,重定向到指定的URL,如果不指定http状态码,使用默认的状态码”302“:”Found“,

res.redirect('/foo/bar');
res.redirect('http://example.com');
res.redirect(301, 'http://example.com');
res.redirect('../login');

重定向可以是一个完整的URL,这样会重定向到一个不同的站点上。

res.redirect('http://google.com');

重定向也可以相对于所在主机的根目录,例如,如果你的程序运行在:http://example.com/admin/post/new上下面的代码将会重定向到如下地址:http://example.com/admin

res.redirect('/admin');

重定向也可以相对于当前的URL,例如:从http://example.com/blog/admin/这个地址(注意反斜杠),下面的代码将会重定向到地址:http://example.com/blog/admin/post/new

res.redirect('post/new')

在从地址: http://example.com/blog/admin重定向到 post/new,如果没有反斜杠的话将会重定向到:http://example.com/blog/post/new

如果你感觉上面的行为很迷惑,想想文件目录和文件的路径,这会让你更好理解。

相对路径的重定向也是允许的,如果你的地址是: http://example.com/admin/post/new,下面的代码将会重定向到http//example.com/admin/post这个地址:

res.redirect('..');

back重定向,重定向到请求的referer,当没有referer请求头的情况下,默认为‘/'

res.redirect('back');

URL重定向原理

Express URL跳转(重定向)的实现方法

进行URL重定向时,服务器只在响应信息的HTTP头信息中设置了HTTP状态码和Location头信息。

当状态码为301或302时(301-永久重定向、302-临时重定向),表示资源位置发生了改变,需要进行重定向。

Location头信息表示了资源的改变的位置,即:要跳重定向的URL。

 location()与redirect()的比较

Express的response对象,是对Node.js原生对象ServerResponse的扩展。location()方法只会设置Location头,而redirect()方法除了会设置Location头外还可自动或手头设置HTTP状态码。理论上讲两者可以实现重定向。

location()方法实现过程大致如下:

res.location = function(url){
 var req = this.req;

 // "back" 是 referrer的别名
 if ('back' == url) url = req.get('Referrer') || '/';

 // 设置Lcation
 this.setHeader('Location', url);
 return this;
};

从以上代码可以看出,location()方法本质上是调用了ServerResponse对象的setHeader()方法,但并没有设置状态码。通过location()设置头信息后,其后的代码还会执行。

使用location()方法实现URL的重定向,还要手动设置HTTP状态码:

res.location('http://itbilu.com');
res.statusCode = 301;

如果需要立即返回响应信息,还要调用end()方法:

res.location('http://itbilu.com');
res.statusCode = 301;
res.end('响应的内容');

// 或
res.location('http://itbilu.com');
res.sent(302);

redirect()方法实现过程大致如下:

res.redirect = function(url){
 var head = 'HEAD' == this.req.method;
 var status = 302;
 var body;

 // 一些处理
 ……

 // 通过 location 方法设置头信息
 this.location(url);
 
 // 另一些处理
 ……

 // 设置状态并返回响应
 this.statusCode = status;
 this.set('Content-Length', Buffer.byteLength(body));
 this.end(head ? null : body);
};

从以上代码可以看出,redirect()方法是对location()方法的扩展。通过location()设置Loction头后,设置HTTP状态码,最后通过ServerResponse对象的end()方法返回响应信息。调用redirect()方法后,其后的代码都不会被执行

重定向与不重定向

在使用的过程中,redirect()方法大多能重定向成功,而location()方法则不太确定,有时可以成功有时不能成功。这与我们的用法有关。

上面讲过,URL重定向是在浏览器端完成的,而URL重定向与HTTP状态码和Location头有关。浏览器首先会判断状态码,只有当状态码是:301或302时,才会根据Location头中的URL进行跳转。

所以,使用location()设置头信息,而不设置状态码或状态码不是301或302,并不会发生重定向:

res.location('http://itbilu.com');
res.sent(200);

而使用redirect()设置的状态码不是301或302也不会发生跳转:

res.redirect(200, 'http://itbilu.com');

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
DHTML 中的绝对定位
Nov 26 Javascript
JavaScript 设计模式学习 Singleton
Jul 27 Javascript
jQuery中animate动画第二次点击事件没反应
May 07 Javascript
javascript与jquery中的this关键字用法实例分析
Dec 24 Javascript
AngularJS中的过滤器filter用法完全解析
Apr 22 Javascript
快速使用Bootstrap搭建传送带
May 06 Javascript
vue时间格式化实例代码
Jun 13 Javascript
JavaScript之面向对象_动力节点Java学院整理
Jun 29 Javascript
js实现canvas图片与img图片的相互转换的示例
Aug 31 Javascript
vue.js 获取select中的value实例
Mar 01 Javascript
js消除图片小游戏代码
Dec 11 Javascript
node.js基础知识汇总
Aug 25 Javascript
微信小程序 首页制作简单实例
Apr 07 #Javascript
微信小程序 商城开发(ecshop )简单实例
Apr 07 #Javascript
js控制文本框禁止输入特殊字符详解
Apr 07 #Javascript
ES6学习笔记之Set和Map数据结构详解
Apr 07 #Javascript
Vue表单验证插件Vue Validator使用方法详解
Apr 07 #Javascript
js 数字、字符串、布尔值的转换方法(必看)
Apr 07 #Javascript
利用js的闭包原理做对象封装及调用方法
Apr 07 #Javascript
You might like
关于查看MSSQL 数据库 用户每个表 占用的空间大小
2013/06/21 PHP
DOM基础及php读取xml内容操作的方法
2015/01/23 PHP
PHP基于curl模拟post提交json数据示例
2018/06/22 PHP
PHP的HTTP客户端Guzzle简单使用方法分析
2019/10/30 PHP
用js实现的模拟jquery的animate自定义动画(2.5K)
2010/07/20 Javascript
JQuery与JS里submit()的区别示例介绍
2014/02/17 Javascript
文本域光标操作的jQuery扩展分享
2014/03/10 Javascript
javascript实现dom动态创建省市纵向列表菜单的方法
2015/05/14 Javascript
asp.net中oracle 存储过程(图文)
2015/08/12 Javascript
ECMA5数组的新增方法有哪些及forEach()模仿实现
2015/11/03 Javascript
jQuery实现模拟flash头像裁切上传功能示例
2016/12/11 Javascript
JavaScript与JQUERY获取元素的宽、高和位置
2017/02/26 Javascript
H5实现仿flash效果的实现代码
2017/09/29 Javascript
vue.js实现插入数值与表达式的方法分析
2018/07/06 Javascript
在create-react-app中使用css modules的示例代码
2018/07/31 Javascript
关于node-bindings无法在Electron中使用的解决办法
2018/12/18 Javascript
基于layui的table插件进行复选框联动功能的实现方法
2019/09/19 Javascript
详解vue中v-bind:style效果的自定义指令
2020/01/21 Javascript
操作Windows注册表的简单的Python程序制作教程
2015/04/07 Python
使用PyV8在Python爬虫中执行js代码
2017/02/16 Python
插入排序_Python与PHP的实现版(推荐)
2017/05/11 Python
python Opencv将图片转为字符画
2021/02/19 Python
用TensorFlow实现戴明回归算法的示例
2018/05/02 Python
pandas数据清洗,排序,索引设置,数据选取方法
2018/05/18 Python
连接pandas以及数组转pandas的方法
2019/06/28 Python
利用pandas合并多个excel的方法示例
2019/10/10 Python
浅析使用Python搭建http服务器
2019/10/27 Python
详解Anaconda 的安装教程
2020/09/23 Python
中学老师的自我评价
2013/11/07 职场文书
小学毕业感言300字
2014/02/19 职场文书
地质灾害防治方案
2014/05/14 职场文书
人民调解协议书范本
2014/10/11 职场文书
股权转让协议范本
2014/12/07 职场文书
员工开除通知书
2015/04/25 职场文书
MySQL中distinct和count(*)的使用方法比较
2021/05/26 MySQL
开机音效回归! Windows 11重新引入开机铃声
2021/11/21 数码科技