让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 RuntimeObject() 获取ie里面自定义函数或者属性的集合
Nov 23 Javascript
JavaScript全排列的六种算法 具体实现
Jun 29 Javascript
javascript:json数据的页面绑定示例代码
Jan 26 Javascript
JavaScript二维数组实现的省市联动菜单
May 08 Javascript
jquery实现简单文字提示效果
Dec 02 Javascript
BootstrapValidator超详细教程(推荐)
Dec 07 Javascript
简述vue中的config配置
Jan 23 Javascript
解决vue+element 键盘回车事件导致页面刷新的问题
Aug 25 Javascript
微信小程序-form表单提交代码实例
Apr 29 Javascript
Node.js爬虫如何获取天气和每日问候详解
Aug 26 Javascript
JS+CSS实现3D切割轮播图
Mar 21 Javascript
何时/使用 Vue3 render 函数的教程详解
Jul 25 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实现网站验证码功能【推荐】
2017/02/09 PHP
ThinkPHP5 的简单搭建和使用详解
2018/11/15 PHP
PHP单例模式实例分析【防继承,防克隆操作】
2019/05/22 PHP
PHP常用的类封装小结【4个工具类】
2019/06/28 PHP
PHP实现15位身份证号转18位的方法分析
2019/10/16 PHP
Javascript 的addEventListener()及attachEvent()区别分析
2009/05/21 Javascript
通过隐藏option实现select的联动效果
2009/11/10 Javascript
在JavaScript中获取请求的URL参数
2010/12/22 Javascript
javascript中attribute和property的区别详解
2014/06/05 Javascript
jQuery插件datalist实现很好看的input下拉列表
2015/07/14 Javascript
JavaScript中eval函数的问题
2016/01/31 Javascript
JavaScript 对象字面量讲解
2016/06/06 Javascript
修改js confirm alert 提示框文字的简单实例
2016/06/10 Javascript
Vue.js第三天学习笔记(计算属性computed)
2016/12/01 Javascript
微信小程序实现图片轮播及文件上传
2017/04/07 Javascript
详解.vue文件中监听input输入事件(oninput)
2017/09/19 Javascript
vue组件发布到npm简单步骤
2017/11/30 Javascript
Vue 后台管理类项目兼容IE9+的方法示例
2019/02/20 Javascript
Python实现的检测web服务器健康状况的小程序
2014/09/17 Python
Python脚本实现下载合并SAE日志
2015/02/10 Python
用Python编写一个基于终端的实现翻译的脚本
2015/04/24 Python
Python 串口读写的实现方法
2019/06/12 Python
python实现两个经纬度点之间的距离和方位角的方法
2019/07/05 Python
解决django服务器重启端口被占用的问题
2019/07/26 Python
python点击鼠标获取坐标(Graphics)
2019/08/10 Python
Python实现分数序列求和
2020/02/25 Python
CSS3 Media Queries详细介绍和使用实例
2014/05/08 HTML / CSS
Hotels.com爱尔兰:全球酒店预订
2017/02/24 全球购物
奥巴马就职演讲稿
2014/05/15 职场文书
学校节能减排方案
2014/06/13 职场文书
一份关于丢失公司财物的检讨书
2014/09/19 职场文书
精神文明建设先进个人事迹材料
2014/12/24 职场文书
小马王观后感
2015/06/11 职场文书
MYSQL 表的全面总结
2021/11/11 MySQL
MySQL利用UNION连接2个查询排序失效详解
2021/11/20 MySQL
vue组件冲突之引用另一个组件出现组件不显示的问题
2022/04/13 Vue.js