让angularjs支持浏览器自动填表


Posted in Javascript onNovember 10, 2014

最近有很多前端同学都抱怨说,登陆表单都不能记录自己的账号。这对于用单页面(single-page applications)和使用ajax比较多的网页来说,还是一个蛮普遍的问题。

UserApp是一个使用angularjs构建的WebApp,但是他一直未能支持浏览器的"save password"特性。
下面就列出了一些发现的问题:

表单不能用js动态的插入DOM。
表单必须真正的发出一个POST请求。(不能获取表单内容,然后用ajax发出请求)
当浏览器自动填表后,$scope并不能获得更新后的数据。
Firefox相对来说简单一点,只要表单元素有name属性,触发提交事件之后,它就会自动提醒用户是否记录数据。

<form name="login-form" ng-submit="login()">

    <input id="login" name="login" type="text" ng-model="user.login">

    <input id="password" name="password" type="password" ng-model="user.password">

</form>

firefox记录数据的要求比较简单

让angularjs支持浏览器自动填表

但是firefox有一个问题,在自动填表之后,$scope里的数据并不会更新。所以我google了一下,发现了一些针对此问题的hacks。但是总感觉这些解决方案没必要,因为我需要的只是在提交表单的时候将数据带上,而不是一些很溜逼的数据双向绑定技术。所以我就采用了很简单的办法:在提交表单的时候获取表单元素的值。

$scope.login = function() {

    $scope.user = {

        login: $("#login").val(),

        password: $("#password").val()

    };

    ...

    return false;

};

OK,现在firefox没问题了,但是chrome怎么办呢?

chrome只有在form表单真正发起POST请求的时候才会提示用户是否储存密码,但这样的话就不能用Ajax操作了。

下面是解决办法:

当表单发出Post请求时,用ng-submit截取,返回false将其阻止,同时用ajax提交数据。
当ajax成功返回时,将session储存在cookies里,再将表单重新提交一边。
页面重载的时候会发现已经认证过了,就将其重定向到主页。
这会让页面刷新一次,但也就是登录的时候需要刷新而已,确保页面返回时是同一个地址就行了。
但如果表单是被动态添加进DOM的时候,这个方法仍然不行。解决方案就是在index.html中添加一个隐藏的表单,需要提交数据的时候就将其它表单携带的数据复制到隐藏表单里。

我将它打包成了一个directive:

app.directive("ngLoginSubmit", function(){

return {

    restrict: "A",

    scope: {

        onSubmit: "=ngLoginSubmit"

    },

    link: function(scope, element, attrs) {

        $(element)[0].onsubmit = function() {

            $("#login-login").val($("#login", element).val());

            $("#login-password").val($("#password", element).val());
            scope.onSubmit(function() {

                $("#login-form")[0].submit();

            });

            return false;

        };

    }

};

});

在index.html里隐藏的表单:

<form name="login-form" id="login-form" method="post" action="" style="display: none;">

    <input name="login" id="login-login" type="text">

    <input name="password" id="login-password" type="password">

</form>

临时登录表单

<form name="login-form" autocomplete="on" ng-login-submit="login">

    <input id="login" name="login" type="text" autocomplete="on">

    <input id="password" name="password" type="password" autocomplete="on">

</form>

登录用的controller:

$scope.login = function(submit) {

    $scope.user = {

        login: $("#login").val(),

        password: $("#password").val()

    };
    function ajaxCallback() {

        submit();

    }  
    return false;

};

刷新时会提示是否重新提交表单

让angularjs支持浏览器自动填表

现在这个问题解决了,但是每当你按下f5的时候,浏览器都会提醒你要不要重新提交表单。这确实有点蛋疼,所以我添加了一个pre-login.html文件,隐藏的表单会提交数据到这里,然后再重定向到index.html。

现在OK了~

Javascript 相关文章推荐
JS中的异常处理方法分享
Dec 22 Javascript
javascript中取前n天日期的两种方法分享
Jan 26 Javascript
Javascript实现检测客户端类型代码封包
Dec 03 Javascript
javascript实现checkbox复选框实例代码
Jan 10 Javascript
jQuery+C#实现参数RSA加密传输功能【附jsencrypt.js下载】
Jun 26 jQuery
AngularJS表单验证功能
Oct 19 Javascript
Node.js使用MySQL连接池的方法实例
Feb 11 Javascript
Bootstrap 按钮样式与使用代码详解
Dec 09 Javascript
jquery+ajax实现上传图片并显示上传进度功能【附php后台接收】
Jun 06 jQuery
原生js实现的移动端可拖动进度条插件功能详解
Aug 15 Javascript
js单线程的本质 Event Loop解析
Oct 29 Javascript
js+canvas实现五子棋小游戏
Aug 02 Javascript
使用cluster 将自己的Node服务器扩展为多线程服务器
Nov 10 #Javascript
前端必备神器 Snap.svg 弹动效果
Nov 10 #Javascript
浅谈JavaScript 框架分类
Nov 10 #Javascript
使用script的src实现跨域和类似ajax效果
Nov 10 #Javascript
jquery插件推荐 jquery.cookie
Nov 09 #Javascript
jquery插件推荐浏览器嗅探userAgent
Nov 09 #Javascript
Javascript限制网页只能在微信内置浏览器中访问
Nov 09 #Javascript
You might like
php 定界符格式引起的错误
2011/05/24 PHP
PHP使用in_array函数检查数组中是否存在某个值
2015/03/25 PHP
PHP+MySQL之Insert Into数据插入用法分析
2015/09/27 PHP
thinkphp3.2.3版本的数据库增删改查实现代码
2016/09/22 PHP
PHP中的使用curl发送请求(GET请求和POST请求)
2017/02/08 PHP
goto语法在PHP中的使用教程
2020/09/17 PHP
用JavaScript脚本实现Web页面信息交互
2006/12/21 Javascript
xtree.js 代码
2007/03/13 Javascript
jBox 2.3基于jquery的最新多功能对话框插件 常见使用问题解答
2011/11/10 Javascript
javascrip关于继承的小例子
2013/05/10 Javascript
解析jQuery的三种bind/One/Live事件绑定使用方法
2013/12/30 Javascript
浅谈nodeName,nodeValue,nodeType,typeof 的区别
2015/01/13 Javascript
JQuery显示隐藏DIV的方法及代码实例
2015/04/16 Javascript
JS实现一次性弹窗的方法【刷新后不弹出】
2016/12/26 Javascript
史上最全JavaScript常用的简写技巧(推荐)
2017/08/17 Javascript
纯JavaScript实现实时反馈系统时间
2017/10/26 Javascript
vue2.0+SVG实现音乐播放圆形进度条组件
2019/09/21 Javascript
原生javascript如何实现共享onload事件
2020/07/03 Javascript
Swiper实现导航栏滚动效果
2020/10/16 Javascript
Python2.7 实现引入自己写的类方法
2018/04/29 Python
分享一下Python数据分析常用的8款工具
2018/04/29 Python
Python3中的列表生成式、生成器与迭代器实例详解
2018/06/11 Python
python合并已经存在的sheet数据到新sheet的方法
2018/12/11 Python
Python实现E-Mail收集插件实例教程
2019/02/06 Python
python 利用pandas将arff文件转csv文件的方法
2019/02/12 Python
django自带调试服务器的使用详解
2019/08/29 Python
python调用函数、类和文件操作简单实例总结
2019/11/29 Python
解析HTML5的存储功能和web SQL的相关操作方法
2016/02/19 HTML / CSS
印度首选时尚目的地:Reliance Trends
2018/01/17 全球购物
成人毕业生自我鉴定
2013/10/18 职场文书
毕业生就业自荐信
2013/12/04 职场文书
怎样填写就业意向
2014/04/02 职场文书
信访工作汇报材料
2014/10/27 职场文书
2014年平安夜寄语
2014/12/08 职场文书
离婚案件被告代理词
2015/05/23 职场文书
CSS3实现的3D隧道效果
2021/04/27 HTML / CSS