例如,很多登录表单希望用户输入用户名和口令,但是,安全考虑,提交表单时不传输明文口令,而是口令的MD5。普通JavaScript开发人员会直接修改<input>:
<form method="post" onsubmit="return checkForm()"> <input type="text"> <input type="password"> <button type="submit">Submit</button></form> <script> function checkForm() { var pwd = document.getElementById('password'); // 把用户输入的明文变为MD5: pwd.value = toMD5(pwd.value); // 继续下一步: return true; }</script>
这个做法看上去没啥问题,但用户输入了口令提交时,口令框的显示会突然从几个*变成32个*(因为MD5有32个字符)。
要想不改变用户的输入,可以利用<input type="hidden">实现:
<form method="post" onsubmit="return checkForm()"> <input type="text"> <input type="password"> <input type="hidden"> <button type="submit">Submit</button></form> <script> function checkForm() { var input_pwd = document.getElementById('input-password'); var md5_pwd = document.getElementById('md5-password'); // 把用户输入的明文变为MD5: md5_pwd.value = toMD5(input_pwd.value); // 继续下一步: return true; }</script>
注意到id为md5-password的<input>标记了name="password",而用户输入的id为input-password的<input>没有name属性。没有name属性的<input>的数据不会被提交。
操作文件
在HTML表单中,可以上传文件的唯一控件就是<input type="file">。
注意:当一个表单包含<input type="file">时,表单的enctype必须指定为multipart/form-data,method必须指定为post,浏览器才能正确编码并以multipart/form-data格式发送表单的数据。
出于安全考虑,浏览器只允许用户点击<input type="file">来选择本地文件,用JavaScript对<input type="file">的value赋值是没有任何效果的。当用户选择了上传某个文件后,JavaScript也无法获得该文件的真实路径:
待上传文件:
通常,上传的文件都由后台服务器处理,JavaScript可以在提交表单时对文件扩展名做检查,以便防止用户上传无效格式的文件:
var f = document.getElementById('test-file-upload'); var filename = f.value; // 'C:\fakepath\test.png' if (!filename || !(filename.endsWith('.jpg') || filename.endsWith('.png') || filename.endsWith('.gif'))) { alert('Can only upload image file.'); return false; }
File API
由于JavaScript对用户上传的文件操作非常有限,尤其是无法读取文件内容,使得很多需要操作文件的网页不得不用Flash这样的第三方插件来实现。
随着HTML5的普及,新增的File API允许JavaScript读取文件内容,获得更多的文件信息。
HTML5的File API提供了File和FileReader两个主要对象,可以获得文件信息并读取文件。
下面的例子演示了如何读取用户选取的图片文件,并在一个<div>中预览图像:
图片预览:
var fileInput = document.getElementById('test-image-file'), info = document.getElementById('test-file-info'), preview = document.getElementById('test-image-preview'); // 监听change事件: fileInput.addEventListener('change', function () { // 清除背景图片: preview.style.backgroundImage = ''; // 检查文件是否选择: if (!fileInput.value) { info.innerHTML = '没有选择文件'; return; } // 获取File引用: var file = fileInput.files[0]; // 获取File信息: info.innerHTML = '文件: ' + file.name + '<br>' + '大小: ' + file.size + '<br>' + '修改: ' + file.lastModifiedDate; if (file.type !== 'image/jpeg' && file.type !== 'image/png' && file.type !== 'image/gif') { alert('不是有效的图片文件!'); return; } // 读取文件: var reader = new FileReader(); reader.onload = function(e) { var data = e.target.result; // 'data:image/jpeg;base64,/9j/4AAQSk...(base64编码)...' preview.style.backgroundImage = 'url(' + data + ')'; }; // 以DataURL的形式读取文件: reader.readAsDataURL(file); });
上面的代码演示了如何通过HTML5的File API读取文件内容。以DataURL的形式读取到的文件是一个字符串,类似于data:image/jpeg;base64,/9j/4AAQSk...(base64编码)...,常用于设置图像。如果需要服务器端处理,把字符串base64后的字符发送给服务器并用Base64解码就可以得到原始文件的二进制内容。
回调