ホームページ >ウェブフロントエンド >jsチュートリアル >一緒にクッキーを学びましょう

一緒にクッキーを学びましょう

小云云
小云云オリジナル
2018-02-09 14:35:461831ブラウズ

この記事では、主にクッキーについて皆さんと一緒に説明します。中国語でクッキーを理解する必要がある場合、それは Netscape の創設者の 1 人であるルー モントレーによって 1993 年に発明された小さなテキスト ファイルであるはずです。この記事が皆さんのお役に立てれば幸いです。

基本的な登録機能を実装します

Web サイトを開いて Web サイトを閲覧する 2 つの最も一般的な操作は、登録とログインであるため、これら 2 つの機能がどのように実装されているかを検討する必要があります。

ローカル シミュレーションでは、localhost:8080/sign_up と入力すると、ブラウザーが get リクエストを開始し、サーバーが sign_up.html に応答します。 localhost:8080/sign_up的时候,浏览器发起get请求,服务器给你响应sign_up.html

//服务器端代码
if (path === '/sign_up' && method === 'GET') {
    let string = fs.readFileSync('./sign_up.html', 'utf8')
    response.statusCode = 200
    response.setHeader('Content-Type', 'text/html;charset=utf-8')
    response.write(string)
    response.end()
 }

CSS布局的几个小坑

在写sign_up.html的时候,注意几点css知识:

  1. 如果想让你的登录页面的body占满整个屏幕,随着窗口的大小变化而变化的话,可以写

body, html{height: 100%}
//或者
body{min-height: 100%}
html{height: 100%}
//不能这么写
body, html{min-height: 100%}

当然了,实际上这么写就可以了

body{min-height: 100vh}
  1. label标签是display: inline,不能设置宽度,行内元素则会根据行内内容自适应宽度,所以行内元素设置width是没有效果的。改成inline-block就可以了

一緒にクッキーを学びましょう

获得用户的数据

既然是注册的需求,那么我们首要关注的点就是--用户的注册信息我们如何获得呢

选择合理的数据结构存储数据是很重要的。

  1. 每个inputname可以使用数组存储

  2. inputvalue应该使用hash,也就是对象来存储。

  3. 上述的套路会一直用下去,hash+[]的组合。

//使用jq来写
let hash = {}
let $form = $('#signUpForm')
$form.on('submit', (e) => {
  e.preventDefault() //不用form表单的默认提交,而是使用我们的的ajax提交
  let need = ['email', 'password', 'password_confirmation']
  need.forEach((name) => {
  let value = $form.find(`[name=${name}]`).val()
  hash[name] = value
})

最终hash里面存储的就是

{
  'email': '...',
  'password': '...',
  'password_confirmation': '...'
}

到目前为止我们把用户的数据封装到了一个对象里面了。

不过在把hash用ajax发出去之前要先进行一些必要的非空验证

非空验证

主要是检测邮箱是否为空、密码是否为空、两次输入的密码是否一致。

//发起请求之前验证是否为空
if (hash['email'] === '') {
  $form.find('[name="email"]').siblings('.errors').text('请您输入邮箱')
  return false //精髓啊,不然没用了
}
if (hash['password'] === '') {
  $form.find('[name="password"]').siblings('.errors').text('请您输入密码')
  return false //精髓啊,不然没用了
}
if (hash['password_confirmation'] === '') {
    $form.find('[name="password_confirmation"]').siblings('.errors').text('请您再次输入确认密码')
    return false //精髓啊,不然没用了
}
if (hash['password'] !== hash['password_confirmation']) {
  $form.find('[name="password_confirmation"]').siblings('.errors').text('两次输入密码不匹配')
  return false //精髓啊,不然没用了
}
  • 如果忘记写return的话,即使你为空了还是会直接越过这一步检测,去发起ajax请求的,所以一定不要忘了写上return false.

  • 如果仅仅这么写的话会有一个bug。当出现错误提示后,你把信息填对了,错误信息依然显示,这显然是不合理的。应该填入信息后,错误信息就消失的。

一緒にクッキーを学びましょう

 $form.find('.errors').each((index, span) => {
     $(span).text('')
 })

使用上述的jq代码来解决这个bug即可。

非空验证完了之后,意味着浏览器收集用户数据的工作完成了,可以把hash发到服务器端了,接下来就是ajax请求了。

使用ajax提交数据

$.post('/sign_up', hash)
.then((response) => {
  //成功了就打印这个  
  console.log(response)
},
() => {
  //错误了打印这个
})

服务器端解析formData

因为formData是一段一段上传的(具体原因略复杂,可以取极限法,如果formdata很多,不可能一下子上传过来),自己不会写,就去搜索代码片段解析formdata

google: node get post data

把获得的代码封装成了一个函数

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)
      })
    }
  )

}

如何使用上述代码片段呢

...
if (path === '/sign_up' && method === 'POST') {
    readBody(request).then((body) => {
      let strings = body.split('&') //['email=1', 'password=2', 'password_confirmmation=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] = decodeURIComponent(value)//hash['email'] = '1'
      })
      let {email, password, password_confirmation} = hash //ES6的解构赋值
  }
  ...

当服务器端接收到了所有的formdata数据后,其实是一串形如email=1&password=2&password_confirmation=3

的字符串,所以我们考虑使用&字符分割成数组。

  • 得到一个形如['email=1', 'password=2', 'confirmation=3']的数组之后,我们为了得到string = 'email=1'这种形式的,开始遍历数组,把数组的每个元素按照=分割,得到 [email, 1]

  • 用第二小节提供的hash+[]方法,处理成hash

服务器端简单的校验

既然服务器端已经获得了formdata

let email = hash['emai']
let password = hash['password']
let password_confirmation = hash['password_confirmation']

CSS レイアウトのいくつかの落とし穴

sign_up.html を記述するときは、CSS の知識に注意してください:

  1. If Ifログイン ページの本文を画面全体に表示し、ウィンドウのサイズの変更に合わせて変更したい場合は、次のように記述できます

let {email, password, password_confirmation} = hash
もちろん、実際には次のように記述するだけです

if (email.indexOf('@') === -1) {
  response.statusCode = 400
  response.write('email is bad') //单引号只是为了标记这是一个字符串
}

  1. labelラベルは display: inline であり、インライン要素は幅を設定できません。インラインコンテンツに応じて自動的に調整されるので、 インライン要素に幅を設定しても効果はありません。それを inline-block に変更するだけです

一緒にクッキーを学びましょう

ユーザーのデータを取得します🎜🎜これは登録要件であるため、最初に焦点を当てるのはユーザーの登録情報です。取得方法それ🎜🎜データを保存するために合理的なデータ構造を選択することが非常に重要です。 🎜
  1. 🎜 各 inputname は、配列を使用して保存できます🎜
  2. 🎜input の value は、オブジェクトである hash を使用して保存する必要があります。 🎜
  3. 🎜上記のルーチンは、hash+[] の組み合わせで引き続き使用されます。 🎜
console.log(email.indexOf('@'))
console.log(email)
🎜 結局、hash に格納されるのは 🎜
hash[key] = decodeURIComponent(value)
🎜 ここまでで、ユーザーのデータをオブジェクトにカプセル化しました。 🎜🎜ただし、Ajax を使用してハッシュを送信する前に、必要な空でない検証を実行する必要があります🎜🎜空でない検証🎜🎜これは主に、電子メールが空であるかどうか、パスワードが空であるかどうか、および 2 回入力されたパスワードが空であるかどうかを検出します。一貫性のある。 🎜
if (email.indexOf('@') === -1) {
  response.statusCode = 400
  response.setHeader('Content-Type', 'application/json;charset=utf-8') //直接告诉浏览器我是json
  response.write(`
    {
      "errors": {
      "email": "invalid"
      }
    }
  `)
}
  • 🎜 return を書き忘れた場合は、それが空であっても、この検出ステップを直接スキップして、ajax リクエストを開始することになるので、忘れないでください。 return false.🎜
  • 🎜このように書くとバグが発生します。エラーメッセージが表示され、情報を正しく入力してもエラーメッセージが表示されるのは明らかに不合理です。情報を入力すると、エラー メッセージが表示されなくなります。 🎜
🎜一緒にクッキーを学びましょう🎜
$.post('/sign_up', hash)
.then((response) => {
  //成功了就打印这个  
  console.log(response)
},
(request, b, c) => {
   console.log(request)
   console.log(b)
   console.log(c)
})
🎜このバグを解決するには、上記の jq コードを使用してください。 🎜🎜空ではないことの検証が完了すると、ブラウザがユーザーデータの収集作業を完了したことになり、ハッシュをサーバーに送信できるようになります。次のステップは、ajax リクエストです。 🎜🎜ajaxを使ってデータを送信🎜
(request) => {
  let {errors} = request.responseJSON    
  if (errors.email && errors.email === 'invalid') {
    $form.find('[name="email"]').siblings('.errors').text('您输入的邮箱错啦')
  }
}
🎜サーバーサイドでformDataを解析する🎜🎜formDataを少しずつアップロードするため(具体的な理由は少し複雑なので、極端な方法を使用できますが、formDataが大量にある場合は不可能です)すべてを一度にアップロードするには)、自分で書くことはできません。formdata を解析するためのコード スニペットを検索するだけです🎜🎜google: node get post data🎜🎜取得したコードを関数にカプセル化します🎜
var users = fs.readFileSync('./db/users', 'utf8')
try {
  users = JSON.parse(users) //[] JSON也支持数组
} catch (exception) {
  users = []
}
let inUse = false
for (let i = 0; i 5c01789b43386e82e3aac0340e7fb38e {
  //成功了就打印这个  
  console.log(response)
},
(request, b, c) => {
   console.log(request)
   console.log(b)
   console.log(c)
})

忘记了错误函数里面的参数是啥了,那就都打印出来看看。

一緒にクッキーを学びましょう

可以看到,如果没用JSON的话,request对象里面有一个后端写的responseText属性可以利用。

一緒にクッキーを学びましょう

设置了Content-Type:application/json;charset=utf-8之后,可以利用多出来的responseJSON属性,获得json的内容啊。

最终失败函数里面写

(request) => {
  let {errors} = request.responseJSON    
  if (errors.email && errors.email === 'invalid') {
    $form.find('[name="email"]').siblings('.errors').text('您输入的邮箱错啦')
  }
}

校验邮箱是否已经存在了

var users = fs.readFileSync('./db/users', 'utf8')
try {
  users = JSON.parse(users) //[] JSON也支持数组
} catch (exception) {
  users = []
}
let inUse = false
for (let i = 0; i < users.length; i++) {
  let user = users[i]
  if (user.email === email) {
    inUse = true
    break
  }
}
if (inUse) {
  response.statusCode = 400
  response.setHeader('Content-Type', 'application/json;charset=utf-8')
  response.write(`
    {
      "errors": {
      "email": "inUse"
      }
    }
  `)
}

本文并没有使用真正意义上的数据库,只是使用了简单的db文件做数据库,其实就是存的数组,也就是users其实就是数组[]

  • 之所以使用了try{}catch(){},是因为一旦除了错,可以将其初始化为空数组,后续代码可以继续执行,可能并不严谨,不过本文是侧重了解注册的思路的。

同样的,如果邮箱已经存在了,就提示用户

if (errors.email && errors.email === 'inUse') {
    $form.find('[name="email"]').siblings('.errors').text('这个邮箱已被注册啦')
}

后端校验必须很严格,因为可以通过curl越过前端的校验。

一緒にクッキーを学びましょう

一緒にクッキーを学びましょう


把信息写入数据库

没有错误之后,就可以把信息写到数据库里面啦

 users.push({email: email, password: password})//是个对象啊
 var usersString = JSON.stringify(users)
 fs.writeFileSync('./db/users', usersString)
 response.statusCode = 200

users实现是个对象,而对象是内存里面的东西,数据库里面应该存储的是字符串,所以用了JSON.stringify(users)

相关推荐:

JS前端缓存的实现方法及 Cookie的特点介绍

全面掌握Express cookie-parser中间件

JavaScript读取和写入cookie实例教程

以上が一緒にクッキーを学びましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。