复习初级知识
响应头:Cookie、Session、Cache-Control等
HTTP知识回顾:
如果要用JavaScript发请求用到下列代码
用node.js收请求,打开方方的server.js,直接访问设置路径,设置响应头,返回字符串,结束
下面以注册登录为需求来介绍Cookie,用node.js写注册登录,并保持一直登录。
登录注册
- 加一个路由
else if(path === '/sign_up'){
var string = fs.readFileSync('./sign_up.html','utf8')
response.statusCode = 200
response.setHeader('Content-Type', 'text/html;charset=utf-8')
response.write('string')
response.end()
}
这就是sign_up的路由。
运行一下server,即node server,node server 8080
访问http://127.0.0.1:8080加后缀sign_up.html 即 http://127.0.0.1:8080/sign_up.html
右键检查,打开控制台,单击network,重新加载页面,查看sign_up.html的Response,然后再看Headers的响应头和请求头,一定要点viewsource。
- 新开一个窗口写代码,开始编辑sign_up.html
form里面用AJAX来做
注册
用form-wrapper的div把 以上所有 包裹起来。
让它样式好看一点,开始写CSS
- 点注册按钮就发送给服务器,服务器验证:邮箱里面有@、密码和确认密码是否一致。所以下面开始写jq,采用bootcdn里的jquery.min.js,再下面写自己的js(给form一个
id="signUpForm"
)
得到类似排序算法的计数排序的hash
- 有了上面的hash,就可以用ajax
$.post('/sign_up',hash)
.then((response)=>{
console.log(response)
},()=>{
console.log(error)
})
把之前的路由修改为else if(path === '/sign_up' && method === 'GET')
,并增加一个路由else if(path === '/sign_up' && method === 'POST'){}
接下来就要读取用户输入的数据,node.js很弱,要借助工具,搜索node http get post data
,打开第一个链接,选择并复制下面这段代码:
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
// at this point, `body` has the entire request body stored in it as a string
});
粘贴到server.js
else if(path === '/sign_up' && method === 'POST'){
let body = []
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
console.log(body)
response.statusCode = 200
response.end()
});
}
封装这个获得用户输入数据的函数
function readBody(request){
return new Promise((resolve,reject)=>{
let body = []
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString();
resolve(body)
})
})
}
上面路由的代码修改为
else if(path === '/sign_up' && method === 'POST'){
readBody(request).then((body)=>{
let strings = body.split('&')//将body字符串分裂成数组['email=1','password=2','password_confirmation=3']
let hash = {}
strings.forEach((string)=>{
//string =='email=1'
let parts = string.split('=')//['email','1']
let key = parts[0]
let value = parts[1]
hash[key] = value//hash['email'] = '1'
})
console.log(hash)
response.statusCode = 200
response.end()
})
}
sign_up.html是客户端把客户录入的信息变成字符串,server.js服务端把这个字符串解析出来。这就是前端向后台传输数据的过程。
- 修改错误提示为JSON对象语法的字符串
if(email.indexOf('@') = -1){
response.statusCode = 400
response.setHeader('Content-Type', 'application/json;charset=utf-8')
response.write(`{
"errors":{
"email":"invalid"
}
}`)
}
客户端当邮箱输入错误时,会得到怎样的提示
$.post('/sign_up',hash)
.then((response)=>{
console.log(response)
},(request)=>{
let {errors} = request.responseJSON
if(errors.email && errors.email ==='invalid'){
alert('你的邮箱输错了')
}
})
优化页面的错误提示
给这三个input后面都加上
if(errors.email && errors.email ==='invalid'){
$('#signUpForm'),find('[name="email"]'),siblings('.error')
.test('邮箱格式错误')
并预留出弹错文字的空间,给.form-wrapper
增加min-width: 350px;
如果用户没有填邮箱,就点注册,则前端就验证了,在$.post之前就验证这个hash
if(hash['email'] === ''){
$('#signUpForm'),find('[name="email"]'),siblings('.error')
.test('填邮箱啊同学')
return
}
if(hash['password'] === ''){
$('#signUpForm'),find('[name="password"]'),siblings('.error')
.test('填密码啊同学')
return
}
if(hash['password_confirmation'] === ''){
$('#signUpForm'),find('[name="password_confirmation"]'),siblings('.error')
.test('确认密码啊同学')
return
}
if(hash['password'] !== 'password_confirmation'){
$('#signUpForm'),find('[name="password_confirmation"]'),siblings('.error')
.test('密码不匹配')
return
}
发现一个问题,之前填的没有消失,一开始找到所有error,设置为空
$('#signUpForm'),find('.error'),each((index,span)=>{
$(span).text('')
})
- 接下来,做正式的登录
首先,从服务器开始,它会把email和password存下来,准备一个数据库db/users,初始一下users里面放置[](它就是一个用JSON语法表示的空数组)
else if(password !== password_confirmation){
response.statusCode = 400
response.write('password not match')
}else{
var users = fs.readFileSync('./db/uesers','utf8')
users = JSON.parse(users)//[]
users.push({email:email,password:password})
var usersString = JSON.stringify(users)//字符串化,没人可以存对象
fs.writeFileSync('./db/users',usersString)
response.statusCode = 200
}
response.end()
})
}
Lee爵士在发明URL的时候说了,不能有@符号,如果需要,就用%40来代替,因此需要转义hash[key] = decodeURIComponent(value)
做一个判断,邮箱有没有已经注册过,只要已经被注册过就不能再注册了
else if(password !== password_confirmation){
response.statusCode = 400
response.write('password not match')
}else{
var users = fs.readFileSync('./db/uesers','utf8')
try{
users = JSON.parse(users)//[]
}catch(exception){
users = []
}
let inUse = false
for(let i=0;i
邮箱可以注册,现在要输入密码进行登录,下面做登录页面,做个路由
else if(path === '/sign_in'){
var string = fs.readFileSync('/sign_in.html','utf8')
response.setHeader('Content-Type', 'text/html;charset=utf-8')
response.write('string')
response.end()
}
创建一个sign_in.html
,复制sign_up.html
的全部代码,把注册改为登录,把其中的signUpForm修改为signInForm,把sign_up.html改为sign_in.html
修改路由,跟注册的路由相似。
$.post('/sign_in',hash)
.then((response)=>{
window.location.href = '/'//跳到首页
},(request)=>{
alert('邮箱与密码不匹配')//弹框提示错误
})
没有登录也可进入首页,如何阻止这个bug,引入今天的主题
-
1⃣️如果没有登录就不让你进来,2⃣️我登录之后能否把我的名字显示在首页上。引入Cookie
总结Cookie特点:
1.服务器通过Set-Cookie响应头设置Cookie
2.浏览器得到Cookie之后,每次请求都要带上Cookie
3.服务器读取Cookie就知道登录用户的信息了(email)
问题:
1.我在Chrome登录了得到Cookie,用Safari访问,Safari会带上Cookie吗?不会
2.Cookie存在哪?
存在电脑硬盘的一个秘密文件里
3.票能作假吗?可以
4.Cookie有有效期吗?默认有效期为20分钟左右,后端可以强制设置有效期
5.Cookie 遵守同源策略吗?
也有,不过跟 AJAX 的同源策略稍微有些不同。
当请求 qq.com 下的资源时,浏览器会默认带上 qq.com 对应的 Cookie,不会带上 baidu.com 对应的 Cookie
当请求 v.qq.com 下的资源时,浏览器不仅会带上 v.qq.com 的Cookie,还会带上 qq.com 的 Cookie
另外 Cookie 还可以根据路径做限制,请自行了解,这个功能用得比较少。
2⃣️我登录之后能否把我的名字显示在首页上。
if(path === '/'){
var string = fs.readFileSync('./index.html','utf8')
let cookies = request.headers.cookie.split('; ')
let hash ={}
for(let i=0;i