Cookie
http协议:(超文本传输协议)是一个基于请求与响应模式的、无状态的、应用层的协议,常基于TCP的连接方式,HTTP1.1版本中给出一种持续连接的机制,绝大多数的Web开发,都是构建在HTTP协议之上的Web应用。
JavaScript 可以使用 document.cookie 属性来创建 、读取、及删除 cookie。
JavaScript 中,创建 cookie 如下所示:
document.cookie="username=John Doe";
您还可以为 cookie 添加一个过期时间(以 UTC 或 GMT 时间)。默认情况下,cookie 在浏览器关闭时删除:
document.cookie="username=John Doe;
expires=Thu, 18 Dec 2043 12:00:00 GMT";
您可以使用 path 参数告诉浏览器 cookie 的路径。默认情况下,cookie 属于当前页面。
document.cookie="username=John Doe; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/";
使用 JavaScript 修改 Cookie
在 JavaScript 中,修改 cookie 类似于创建 cookie,如下所示:
document.cookie="username=John Smith; expires=Thu, 18 Dec 2043 12:00:00 GMT; path=/";
旧的 cookie 将被覆盖。
使用 JavaScript 删除 Cookie
删除 cookie 非常简单。您只需要设置 expires 参数为以前的时间即可,如下所示,设置为 Thu, 01 Jan 1970 00:00:00 GMT:
document.cookie = "username=; expires=Thu, 01 Jan 1970 00:00:00 GMT";
注意,当您删除时不必指定 cookie 的值。
封装三个函数实现创建,获取,查找cookie
代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<head>
<script>
function setCookie(cname,cvalue,exdays){
var d = new Date();
d.setTime(d.getTime()+(exdays*24*60*60*1000));
var expires = "expires="+d.toGMTString();
document.cookie = cname+"="+cvalue+"; "+expires;
console.log(document.cookie)
}
function getCookie(cname){
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name)==0) { return c.substring(name.length,c.length); }
}
return "";
}
function checkCookie(){
var user=getCookie("username");
if (user!=""){
alert("欢迎 " + user + " 再次访问");
}
else {
user = prompt("请输入你的名字:","");
if (user!="" && user!=null){
setCookie("username",user,30);
}
}
}
</script>
</head>
<body onload="checkCookie()"></body>
</html>
cookie实现七天免登陆的小例子
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
function setCookie(cname, cvalue, exdays) {
var d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
var expires = "expires=" + d.toGMTString();
document.cookie = cname + "=" + cvalue + "; " + expires;
console.log(document.cookie)
}
function getCookie(cname) {
var name = cname + "=";
var ca = document.cookie.split(';');
for (var i = 0; i < ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name) == 0) { return c.substring(name.length, c.length); }
}
return "";
}
function checkCookie() {
var user = getCookie("username");
if (user != "") {
alert("欢迎 " + user + " 再次访问");
}
else {
user = prompt("请输入你的名字:", "");
if (user != "" && user != null) {
setCookie("username", user, 30);
}
}
}
window.onload = function () {
var aInput = document.getElementsByTagName("input");
if (getCookie("username")) {
aInput[0].value = getCookie("username");
aInput[1].value = getCookie("password");
}
aInput[3].onclick = function () {
var username = aInput[0].value;
var password = aInput[1].value;
if (aInput[2].checked) {
setCookie("username", username, 7);
setCookie("password", password, 7);
}
}
}
</script>
</head>
<body>
用户名: <input type="text">
密码: <input type="password">
<label> <input type="checkbox"> 七天免登陆 </label>
<input type="button" value="登陆">
</body>
</html>
正则表达式
正则表达式是由普通字符以及特殊字符组成的对字符串进行过滤的逻辑公式。
什么是正则表达式?
正则表达式是由一个字符序列形成的搜索模式。
当你在文本中搜索数据时,你可以用搜索模式来描述你要查询的内容。
正则表达式可以是一个简单的字符,或一个更复杂的模式。
正则表达式可用于所有文本搜索和文本替换的操作。
正则表达式的语法:
/正则表达式主体/修饰符(可选)
其中修饰符是可选的。实例:
var patt = /runoob/i
实例解析:
/runoob/i 是一个正则表达式。
runoob 是一个正则表达式主体 (用于检索)。
i 是一个修饰符 (搜索不区分大小写)。
正则表达式的创建
方法1:字面量方式
var reg = /abc/;
方法2:构造函数
var rag = new RegExp("abc");
字符串方法
正则表达式中常用的字符串方法有search()和replace()。
search() 方法 用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串,并返回子串的起始位置。【注】下标是从0开始。
replace() 方法 用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
search()方法中,可以使用正则表达式当参数,也可以使用字符串当参数。字符串参数会转换为正则表达式。
replace(参数1,参数2)。参数1是要被替换的字串,可以使用正则表达式,也可以使用字符串,使用字符串时,会将字符串转换为正则表达式。参数2是要替换的新字串。
test()方法
test() 方法是一个正则表达式方法。
test() 方法用于检测一个字符串是否匹配某个模式,如果字符串中含有匹配的文本,则返回 true,否则返回 false。
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function(){
// 使用字面量方式创建
// var reg = /abc/;
// 使用正则表达式创建
var rag = new RegExp("abc");
// 创建一个字符串
var str = "abbbabc";
// 使用test检测
var flag = rag.test(str);
console.log(flag);
}
</script>
</head>
<body>
</body>
</html>
exec()方法
exec() 方法是一个正则表达式方法。
exec() 方法用于检索字符串中的正则表达式的匹配。
该函数返回一个数组,其中存放匹配的结果。如果未找到匹配,则返回值为 null。
exec() 方法的功能非常强大,它是一个通用的方法,而且使用起来也比 test() 方法以及支持正则表达式的 String 对象的方法更为复杂。
如果 exec() 找到了匹配的文本,则返回一个结果数组。否则,返回 null。此数组的第 0 个元素是与正则表达式相匹配的文本,第 1 个元素是与 RegExpObject 的第 1 个子表达式相匹配的文本(如果有的话),第 2 个元素是与 RegExpObject 的第 2 个子表达式相匹配的文本(如果有的话),以此类推。除了数组元素和 length 属性之外,exec() 方法还返回两个属性。index 属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string。我们可以看得出,在调用非全局的 RegExp 对象的 exec() 方法时,返回的数组与调用方法 String.match() 返回的数组是相同的。
但是,当 RegExpObject 是一个全局正则表达式时,exec() 的行为就稍微复杂一些。它会在 RegExpObject 的 lastIndex 属性指定的字符处开始检索字符串 string。当 exec() 找到了与表达式相匹配的文本时,在匹配后,它将把 RegExpObject 的 lastIndex 属性设置为匹配文本的最后一个字符的下一个位置。这就是说,您可以通过反复调用 exec() 方法来遍历字符串中的所有匹配文本。当 exec() 再也找不到匹配的文本时,它将返回 null,并把 lastIndex 属性重置为 0。
重要事项:如果在一个字符串中完成了一次模式匹配之后要开始检索新的字符串,就必须手动地把 lastIndex 属性重置为 0。
提示:请注意,无论 RegExpObject 是否是全局模式,exec() 都会把完整的细节添加到它返回的数组中。这就是 exec() 与 String.match() 的不同之处,后者在全局模式下返回的信息要少得多。因此我们可以这么说,在循环中反复地调用 exec() 方法是唯一一种获得全局模式的完整模式匹配信息的方法。
代码示例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>测试</title>
<script type="text/javascript">
var str = "Visit W3School Visit W3School Visit W3School";
var patt = new RegExp("W3School", "g");
var result;
while ((result = patt.exec(str)) != null) {
document.write(result);
document.write("<br />");
document.write(patt.lastIndex);
document.write("<br/>")
}
</script>
</head>
<body>
</body>
</html>
正则表达式修饰符
主要用的修饰符有i,g,m
i(ignore):执行对大小写不敏感的匹配
g(global):执行全局匹配(查找所有匹配而非在找到第一个匹配后停止,一般的正则表达式是在找到第一个匹配项后就停止了)
m(more):执行多行匹配
代码示例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
window.onload = function(){
// 使用字面量方式创建一个全局匹配
var reg = /abc/g;
// 创建一个字符串
var str = "abcabc";
// 使用match方法,测试第二个abc能不能被匹配到
var arr = str.match(reg);
// 使用字面量方式创建一个忽略大小写且全局匹配
var reg2 = /abc/ig;
var str2 = "ABCabCAbc"
var arr2 = str2.match(reg2);
console.log(arr)
console.log(arr2)
}
</script>
</head>
<body>
正则表达式的元字符
元字符(Metacharacter)是拥有特殊含义的字符:
. 查找单个字符,除了换行和行结束符。
\w 查找单词字符。等同于数组字母下划线[0-9a-zA-Z_]
\W 查找非单词字符。
\d 查找数字。
\D 查找非数字字符。
\s 查找空白字符。
\S 查找非空白字符。
\b 匹配单词边界。
\B 匹配非单词边界。
\0 查找 NUL 字符。
\n 查找换行符。
\f 查找换页符。
\r 查找回车符。
\t 查找制表符。
\v 查找垂直制表符。
\xxx 查找以八进制数 xxx 规定的字符
\xdd 查找以十六进制数 dd 规定的字符。
\uxxxx 查找以十六进制数 xxxx 规定的 Unicode 字符。
量词
量词的描述:
n+ 匹配任何包含至少一个 n 的字符串。
n* 匹配任何包含零个或多个 n 的字符串。
n? 匹配任何包含零个或一个 n 的字符串。
n{X} 匹配包含 X 个 n 的序列的字符串。
n{X,Y} 匹配包含 X 至 Y 个 n 的序列的字符串。
n{X,} 匹配包含至少 X 个 n 的序列的字符串。
n$ 匹配任何结尾为 n 的字符串。
^n 匹配任何开头为 n 的字符串。
?=n 匹配任何其后紧接指定字符串 n 的字符串。
?!n 匹配任何其后没有紧接指定字符串 n 的字符串。
方括号
方括号用于查找某个范围内的字符:
描述:
[abc] 查找方括号之间的任何字符。
[^abc] 查找任何不在方括号之间的字符。
[0-9] 查找任何从 0 至 9 的数字。
[a-z] 查找任何从小写 a 到小写 z 的字符。
[A-Z] 查找任何从大写 A 到大写 Z 的字符。
[A-z] 查找任何从大写 A 到小写 z 的字符。
[adgk] 查找给定集合内的任何字符。
[^adgk] 查找给定集合外的任何字符。
(red|blue|green) 查找任何指定的选项。
正则表达式分组
正则表达式的分组能够将子表达式做成子集,使用()进行分组,方便对match的字符串进行划分。
一个分组中可以像上面这样有一个具体的表达式,这样可以优雅地表达一个重复的字符串
/hahaha/ —等价于—> /(ha){3}/
体格分组中还可以有多个候选表达式,例如
var reg = /I come from (hunan|hubei|zhejiang)/;
也就是说在这个分组中,通过|隔开的几个候选表达式是并列的关系,所以可以把这个|理解为或的意思
reg.test('I come from hunan'); //true
reg.test('I come from hubei'); //true
常见的分组类型有: 捕获型(),非捕获型(?:),反向前瞻型(?=),正向前瞻型(?!)。我们使用的比较多的都是捕获型分组,只有这种分组才会暂存匹配到的串。
捕获型分组
被正则表达式捕获(匹配)到的字符串会被暂存起来,其中,由分组捕获到的字符串会从1开始编号,于是我们可以引用这些字符串:
var reg = /(\d{4})-(\d{2})-(\d{2})/;
var dateStr = '2018-04-18';
reg.test(dateStr); //true
RegExp.$1 //2018
RegExp.$2 //04
RegExp.$3 //18
结合replace方法做字符串自定义替换。String.prototype.replace方法的传参中可以直接引用被捕获的串,比如我们想开发中常见的日期格式替换,例如后台给你返回了一个2018/04/18,让你用正则替换为2018-04-18,就可以利用分组
var dateStr = '2018/04/18';
var reg = /(\d{4})\/(\d{2})\/(\d{2})/;
dateStr = dateStr.replace(reg, '$1-$2-$3') //"2018-04-18"
反向引用:
正则表达式里也能进行引用,这称为反向引用:
var reg = /(\w{3}) is \1/
reg.test('kid is kid') // true
reg.test('dik is dik') // true
reg.test('kid is dik') // false
reg.test('dik is kid') // false
需要注意的是,如果引用了越界或者不存在的编号的话,就被被解析为普通的表达式
var reg = /(\w{3}) is \6/;
reg.test( 'kid is kid' ); // false
reg.test( 'kid is \6' ); // true
非捕获型分组
有的时候只是为了分组并不需要捕获的情况下就可以使用非捕获型分组,例如
var reg = /(?:\d{4})-(\d{2})-(\d{2})/
var date = '2012-12-21'
reg.test(date)
RegExp.$1 // 12
RegExp.$2 // 21
因为(?:\d{4})只是分组,不捕获,所以第一个分组是(\d{2})
正向与反向前瞻型分组
正向前瞻型分组:你站在原地往前看,如果前方是指定的东西就返回true,否则为false
var reg = /kid is a (?=doubi)/
reg.test('kid is a doubi') // true
reg.test('kid is a shabi') // false
既然前瞻型分组和非捕获型分组都不会捕获,那他们有什么区别呢?先看例子:’
var reg, str = "kid is a doubi";
reg = /(kid is a (?:doubi))/
reg.test(str)
RegExp.$1 // kid is a doubi
reg = /(kid is a (?=doubi))/
reg.test(str)
RegExp.$1 // kis is a
也就是说非捕获型分组匹配到的字符串仍然会被外层分组匹配到,而前瞻型不会,所以如果你希望在外层分组中不匹配里面分组的值的话就可以使用前瞻型分组了