获取egg框架指令:npm init egg -init=simple 下载完成后 npm i下载模块
router.js文件:
router.get("/ajax",controller.home.fn) 表示 路由/ajax 其指向controller文件中的home.js文件中的fn函数
get不能用本地路径当路由
当有两个相同的路由 谁先注册谁先匹配
通配符*必须放最下面 /输入什么都返回这个路由除了上面已有的路由 和本地路径
后端处理顺序:静态文件 > 路由匹配
jsonp:
router.get("/jsonp",app.jsonp({
callback:"sug"
}),controller.home.jsonp)
第二个参数app.jsonp函数中写入一个对象 {callback:"sug"}sug表示key值 在query字段上
use strict';
/**
* @param {Egg.Application} app - egg application
*/
module.exports = app => {
const { router, controller,jsonp } = app;
router.get("/ajax1",controller.home.fn)
router.get("/sina",controller.home.sina)
router.get("/jsonp",app.jsonp({
callback:"sug"
}),controller.home.jsonp)
// 另一个文件的路由
router.get("/add*",controller.car.add)
router.get("/*",controller.home.all)
};
controller:
ctx是egg里的上下文对象 body是成员之一 controller提供的功能
主要使用:给前端发数据功能 访问插件功能
body是一个数据包 相当于end只执行一次就断开
npm i egg-cors 跨域插件
this.ctx.body:向前端发送数据
this.ctx.request 一个数据包 可以加上
1. .query:取出前端请求网址的query部分并对象化
2. .body:前端post发送给egg的参数字段 也就是axios.post(url,{userid:13,pwd:123})第二个参数
3..files:前端POST发送给egg的参数文件
let fname=path.basename(f[0].filepath)这个代码要引入path模块
剪切文件路径的最后一个也就是文件名 把文件名截取出来
f[0]&&fs.renameSync(f[0].filepath,__dirname+"/../public/upload"+fname)
前端传的文件移动到指定位置
let res=await this.ctx.curl(url) axios请求的数据 可以用在后端用await 和 curl网络请求工具直接请求网络数据如sina数据 也就是数据代理
'use strict';
const Controller = require('egg').Controller;
const fs=require("fs")
const path=require("path")
class HomeController extends Controller { //HomeController继承egg的Controller
async index() {
const { ctx } = this;
ctx.body = 'hi, egg';
};
async ajax1(){
async jsonp(){//jsonp
this.ctx.body={info:"ajax数据接口",code:"18280123"}
}
async sina(){//数据代理
var url="https://api.weibo.com/2/statuses/home_timeline.json?access_token=2.00ZmCkcDlel8HDd856f9b9ccsVwsYD"
let res=await this.ctx.curl(url)//curl网络请求工具
// console.log(data);
this.ctx.body=res.data.toString()
}
async get1(){//query解析---axios的第二个参数为核心
// req httpRequestMessage req=request 一个数据包对象
// 1.egg后端get请求的参数
// 2.在浏览器出入/get1?query部分也可以解析
var k=this.ctx.request.query//取出前端网址的query值并对象化
console.log(k);
this.ctx.body={k}
}
async download(){//下载
this.ctx.body=fs.readFileSync(__dirname+'/../public/img/sp1.jpg')
}
async login(){
var k=this.ctx.request.query
console.log(k);
this.ctx.body="666"
}
async post1(){
// 1.前端发送给你egg的参数字段
let obj=this.ctx.request.body
console.log(obj);
this.ctx.body={info:"登录成功",res:obj}
}
async post2(){
// 1.前端post发送给egg的参数字段
let ziduan=this.ctx.request.body
// 2.接收文件
let f=this.ctx.request.files
console.log(f);
let fname=path.basename(f[0].filepath)//path模块 剪切文件路径的最后一个
f[0]&&fs.renameSync(f[0].filepath,__dirname+"/../public/upload"+fname)//移动文件
this.ctx.body={info:"注册成功"}
}
}
module.exports = HomeController;
GET请求传参数给后端
参数会拼接到url(网址)中 不安全 速度快
后端返回的数据 前端是xhr对象接受了 程序员用js使用
传统ajax解析query字段:
ajax上传后端 后端this.ctx.request.query解析出字段
req httpRequestMessage req=request 一个数据包对象
1.egg后端get请求的参数
2.在浏览器出入/get1?query部分也可以解析
var searinout=document.getElementById("searinput")
var xhr=new XMLHttpRequest()
var url="http://192.168.1.3:7001/get1?keywords=4564&xiezi=nazi"
xhr.open("GET",url,true)
xhr.send()
xhr.onreadystatechange=()=>{
if(xhr.readyState==4&&xhr.status==200){
console.log(xhr.responseText);
}
}
async get1(){
var k=this.ctx.request.query//取出前端网址的query值并对象化
console.log(k);
this.ctx.body={k}
}
axios解析query字段:
axios(url,{params:{count:20,key2:searinout}})
axios第二个参数发送后端 后端拼成query对象发回前端
格式 axios(url,{params:{key:xx,key:xx}})
var searinout=document.getElementById("searinput").value
var url="http://192.168.1.3:7001/get1"
axios(url,{params:{count:20,key2:searinout}})//axios第二个参数发送后端 拼成query格式发送
.then(res=>console.log(res))
}
// axios第二个参数拼接query 底层
function myaxios(url,obj){
let arr=Object.keys(obj.params)//keys取出属性名
for(let i=0;i<arr.length;i++){
querystring+=arr[i]+"="+obj.params[arr[i]]
}
querystring&&(url+"?"+querystring)
// 请求url
}
浏览器的地址栏只能发送GET请求
接受的数据会直接读取渲染,如果解析失败会下载
a标签的href属性也只能发送get请求 并且是点击事件触发get请求
发送网络请求给href的网址 后端返回的数据 接收的数据会直接读取渲染 解析失败下载
img-src 不能发送GET请求 只能渲染成图片 非图片编码会碎裂
link-href 只能发get请求 返回的数据按照功能使用
form表单
发送GET/POST/DELETE等等给action属性对应的url
1.用户点击了提交按钮或触发了表单的提交事件
2.把form中的数据全部解析为url的querystring
3.返回的数据 同a标签
a标签: <a href="http://192.168.1.3:7001/get1?跳转=a">a标签</a> 因为get1会解析成query对象
所以a标签跳转的是网址的query对象 {"k":{"跳转":"a"}}
表单请求:
action属性:在点击submit之后返回action请求的数据在页面上
input:name属性为query字段的key值 输入的value为 key的值 点击submit之后在跳转的网址的query部分显示
<form action="http://192.168.1.3:7001/login" enctype="" method="get" target="_blank">
<input type="text" name="aaa"> <!--name是key 输入的内容value是值-->
<input type="text" name="bbb">
<input type="submit" value="123">
</form>
async login(){
var k=this.ctx.request.query
console.log(k);
this.ctx.body="666"
}
文件下载指令:
this.ctx.body=fs.readFileSync(__dirname+'/../public/img/sp1.jpg')
POST:
1.接收GET请求的数据:ctx.request.query 或者 ctx.query
2.接收POST请求的数据:ctx.request.body 而不是 ctx.body
不要把用户的隐私数据 直接拼到url中直接发送给后端
应该转为暗文 用POST
传统post网络请求:
除了open要改成“POST” send函数中也要加字符串 字符串为网址的query部分
var xhr =new XMLHttpRequest()
var url="http://192.168.1.3:7001/post1"
xhr.open("POST",url,true)
xhr.setRequestHeader("Content-type","application/x-www-form-urlencode")
xhr.send("pwd=123&userid=123")//这个函数接受字符串:querystring
// 如果“POST”就会把这个请求的数据放在"请求数据包"-HTTPrequestmessage的请求体中
// 如果是“GET”,不会报错 但是也不会
xhr.onreadystatechange=function(){
if(xhr.readyState==4&&xhr.status==200){
console.log(xhr.responseText);
}
}
POST的axios网络请求:
axios.post() query字段放在第二个参数 与axios.get相似但不用谢params:{} 直接写对象{key:xx,key:xx}
var url="http://192.168.1.3:7001/post1"
axios.post(url,{userid:13,pwd:123})
.then((res)=>{
console.log(res);
})
async post1(){
// 1.前端发送给你egg的参数字段
let obj=this.ctx.request.body
console.log(obj);
this.ctx.body={info:"登录成功",res:obj}
}
后端接收前端文件:
1.request.body获取字段
2.request.files获取发送的文件
3. let fname=path.basename(f[0].filepath) 利用path模块获取文件名
4.f[0]&&fs.renameSync(f[0].filepath,__dirname+"/../public/upload"+fname) 把文件移动到本地指定位置
async post2(){
// 1.前端post发送给egg的参数字段
let ziduan=this.ctx.request.body
//2.前端POST发送给egg的参数文件
let f=this.ctx.request.files
console.log(f);
let fname=path.basename(f[0].filepath)//path模块 剪切文件路径的最后一个
f[0]&&fs.renameSync(f[0].filepath,__dirname+"/../public/upload"+fname)//移动文件
this.ctx.body={info:"注册成功"}
}
前端发送文件:
将上传的文件显示到页面:
var img1=window.URL.createObjectURL(f1.files[0])
box.src=img1
账号:<input type="text" id="userid">
密码:<input type="text" id="pwd">
选择头像<input type="file" id="f1" multiple>
<img src="" alt="" id="box">
<button onclick="fn()">登录</button>
<script>
function fn(){
var f1=document.querySelector("#f1")
var box=document.querySelector("#box")
// 把要给后端发送的大量数据:文件 处理成表单数据
var fdata=new FormData()
fdata.append("userid","123")
fdata.append("pwd","123")
// console.log(f1.files[0]);
fdata.append("touxiang",f1.files[0])
var img1=window.URL.createObjectURL(f1.files[0])
box.src=img1
var url="http://192.168.1.3:7001/post2"
axios.post(url,fdata)
.then((res)=>{
console.log(res);
})
}
将前端传输的文件上传到本地:
先用this.ctx.request.files获取目标文件
在f[0].filepath获取老路径
通过path.basename(oldpath)获取文件名
设置新路径
fs.renameSync(oldpath,newpath)让上传的文件上传到本地指定新路径
async post2(){
// 1.前端post发送给egg的参数字段
let ziduan=this.ctx.request.body
//2.前端POST发送给egg的参数文件
let f=this.ctx.request.files
console.log(f);
if(f[0]){//如果图片存在
let oldpath=f[0].filepath//旧路径
let fname=path.basename(oldpath)//path模块 剪切文件路径的最后一个
let newpath=__dirname+"/../public/upload/"+fname //新路径
fs.renameSync(oldpath,newpath)//传输到新路径
}
this.ctx.body={info:"注册成功6666"}
}