让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 相关文章推荐
JavaScript 获取用户客户端操作系统版本
Aug 25 Javascript
jQuery+CSS 半开折叠效果原理及代码(自写)
Mar 04 Javascript
浅谈jquery中的each方法$.each、this.each、$.fn.each
Jun 23 Javascript
浅谈jquery中ajax跨域提交的时候会有2次请求的问题
Nov 10 jQuery
详解基于Node.js的HTTP/2 Server实践
May 31 Javascript
angularJs在多个控制器中共享服务数据的方法
Sep 30 Javascript
vue-cli 构建骨架屏的方法示例
Nov 08 Javascript
node命令行工具之实现项目工程自动初始化的标准流程
Aug 12 Javascript
Vue页面刷新记住页面状态的实现
Dec 27 Javascript
JS实现简单的表格增删
Jan 16 Javascript
Js视频播放器插件Video.js使用方法详解
Feb 04 Javascript
node+vue实现文件上传功能
May 28 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中的日期处理方法集锦
2007/01/02 PHP
PHP怎么实现网站保存快捷方式方便用户随时浏览
2013/08/15 PHP
PHP根据IP地址获取所在城市具体实现
2013/11/27 PHP
ThinkPHP分页类使用详解
2014/03/05 PHP
PHP实现的QQ空间g_tk加密算法
2015/07/09 PHP
php抓取并保存网站图片的实现代码
2015/10/28 PHP
php利用smtp类实现电子邮件发送
2015/10/30 PHP
PHP实现统计所有字符在字符串中出现次数的方法
2017/10/17 PHP
JavaScript Event学习第四章 传统的事件注册模型
2010/02/07 Javascript
Nodejs使用mysql模块之获得更新和删除影响的行数的方法
2014/03/18 NodeJs
JQuery选择器绑定事件及修改内容的方法
2015/01/23 Javascript
IE下支持文本框和密码框placeholder效果的JQuery插件分享
2015/01/31 Javascript
JavaScript框架是什么?怎样才能叫做框架?
2015/07/01 Javascript
JavaScript实现跨浏览器的添加及删除事件绑定函数实例
2015/08/04 Javascript
原生javascript实现图片无缝滚动效果
2016/02/12 Javascript
jQuery基础的工厂函数以及定时器的经典实例分析
2016/05/20 Javascript
简单实现nodejs上传功能
2017/01/14 NodeJs
JS出现失效的情况总结
2017/01/20 Javascript
详谈js中数组(array)和对象(object)的区别
2017/02/27 Javascript
vue interceptor 使用教程实例详解
2018/09/13 Javascript
解决Vue开发中对话框被遮罩层挡住的问题
2018/11/26 Javascript
atom-design(Vue.js移动端组件库)手势组件使用教程
2019/05/16 Javascript
微信小程序下拉加载和上拉刷新两种实现方法详解
2019/09/05 Javascript
[02:06]DOTA2肉山黑名单魔法终结者 敌法师中文配音鉴赏
2013/06/17 DOTA
Python实现的拟合二元一次函数功能示例【基于scipy模块】
2018/05/15 Python
Python安装与卸载流程详细步骤(图解)
2020/02/20 Python
基于python实现破解滑动验证码过程解析
2020/05/28 Python
ProForm英国站点:健身房和健身器材网上商店
2019/06/05 全球购物
英国水族馆和池塘用品购物网站:Warehouse Aquatics
2019/08/29 全球购物
aden + anais英国官网:美国婴儿贴身用品品牌
2019/09/08 全球购物
安全生产投入制度
2014/01/29 职场文书
冰淇淋开店创业计划书
2014/02/01 职场文书
幼儿园课题方案
2014/06/09 职场文书
我为党旗添光彩演讲稿
2014/09/10 职场文书
公司开业主持词
2015/07/02 职场文书
postgres之jsonb属性的使用操作
2021/06/23 PostgreSQL