## 5.1 Cookies
- **ctx.cookies** 用来读写 Cookie。
- **ctx.cookies.set(key,value)** 设置cookie
- **ctx.cookies.get(key)** 获取cookie
```
const Koa = require('koa')
const compose = require('koa-compose')
const app = new Koa()
const main = ctx => {
const n = Number(ctx.cookies.get('view') || 0) + 1;
ctx.cookies.set('view',n)
ctx.response.body = n + 'views';
}
app.use(main)
app.listen(3000)
# 结果
每刷新一次,页面显示的views会 +1
```
## 5.2 表单
> Web 应用离不开处理表单。本质上,表单就是 POST 方法发送到服务器的键值对。**koa-body**模块可以用来从 POST 请求的数据体里面提取键值对。
```
# 前端访问
function submitHandler(){
let xhr = new XMLHttpRequest();
xhr.open('POST','http://localhost:3000/test',true);
xhr.onreadystatechange=function(){
if(xhr.readyState==4&&xhr.status==200){
console.log(xhr.responseText)
}
}
const data = {
name:formName.inputKey.value
}
xhr.send(JSON.stringify(data))
}
# 后端服务
const Koa = require('koa')
const koaBody = require('koa-body')
const route = require('koa-route')
const fs = require('fs.promised')
const app = new Koa()
const indexHtml = async ctx => {
ctx.response.type = 'html'
ctx.response.body= await fs.readFile('./index.html','utf8')
}
const main = ctx => {
// ctx.response.header=''
const body = JSON.parse(ctx.request.body);
console.log(body)
if (!body.name) ctx.throw(400, '.name required');
ctx.body = { name: body.name };
}
app.use(koaBody())
app.use(route.get('/',indexHtml))
app.use(route.post('/test', main));
app.listen(3000)
```
## 5.3 文件上传
> koa-body模块还可以用来处理文件上传
```
# 前端
<form name='testname'>
<input type="file" name='fileInput' id='fileUpload'>
<button type=button onclick='test()'>提交</button>
</form>
<script>
function test(){
let xhr = new XMLHttpRequest();
const file = document.getElementById('fileUpload')
console.log(file.files)
const formData = new FormData();
formData.append('upfile',file.files[0])
xhr.open('POST','http://localhost:3000/test',true);
xhr.onreadystatechange=function(){
if(xhr.readyState==4&&xhr.status==200){
console.log(xhr.responseText)
}
}
xhr.send(formData)
xhr.timeout=100000;
}
</script>
# 服务端
const Koa = require('koa')
const koaBody = require('koa-body')
const route = require('koa-route')
const fs = require('fs.promised')
const os = require('os')
const path = require('path')
const app = new Koa()
const indexHtml = async ctx => {
ctx.response.type = 'html'
ctx.response.body= await fs.readFile('./index.html','utf8')
}
const main =async ctx => {
const tmpdir = os.tmpdir();
const filePaths = [];
const files = ctx.request.body.files || {};
console.log(ctx.request.body.files)
const file = files.upfile;
const filePath = path.join(tmpdir, file.name); //创建写入目录
const reader = fs.createReadStream(file.path) //读取上传文件
const writer = fs.createWriteStream(filePath)
reader.pipe(writer) //写入文件
filePaths.push(filePath)
ctx.body = filePaths;
}
app.use(koaBody({multipart:true}))
app.use(route.get('/',indexHtml))
app.use(route.post('/test', main));
app.listen(3000)
```
- os模块:os模块为node的内置模块,用于操作系统。
- os.tmpdir :返回一个字符串, 表明操作系统的 默认临时文件目录.
- path.join(tmpdir,file.name) 实现将文件存放到系统默认临时文件目录下
- ctx.request.body.files 为文件上传的内容对象