1.接收客户端数据的语法
1.1GET方式
1.1.1
- 客户端请求:/api/xx?id=1
- 接口写法:app.get(‘api/xx’,(req,res) => { })
- 接口参数:req.body
1.1.2
- 客户端请求:/api/xx/1
- 接口写法:app.get(’/api/xx/:id’)
- 接口参数:req.params
1.2POST方式
1.2.1
- 客户端:content-type:application/x-www-form-urlencoded
- 中间件:app.use(express.urlencoded({extended:false}))
- 接口写法:app.post(‘api/xx’,(req,res) => { })
- 接口参数:req.body
1.2.2
- 客户端:content-type:multipart/form-data
- 加载multer模板:const multer = require(‘multer’)
- 配置上传目录:const upload = multer({dest:‘uploads’})
- 接口写法:app.post(‘api/xx’,upload.single(’ '),(req,res) => { })
- 接口参数:req.body、req.file
2.跨域
2.1同源策略
- 协议、主机地址、端口组成一个**“源”**
- 如果两个url的协议、主机地址、端口都相同,那么这两个url是同源的,否则就是非同源
- 如果非同源,那么以下三种行为会受到限制:Cookie 无法操作、DOM 无法操作、Ajax请求无效(请求可以发送,服务器也会处理这次请求,但是响应结果会被浏览器拦截)
2.2解决跨域
2.2.1JSONP
- JSONP是程序员被迫想出来的解决跨域的方案
- JSONP方案和Ajax没有任何关系
- JSONP方案只支持GET请求
- JSONP没有浏览器兼容问题,任何浏览器都支持
- 原理:
- 客户端利用 script 标签的 src 属性,去请求一个接口,因为src属性不受跨域影响
- 服务端响应一个字符串
- 客户端接收到字符串,然后把它当做JS代码运行
- ajax可以通过dataType:jsonp发起跨域请求
2.2.2CORS
- CORS方案,就是通过服务器设置响应头来实现跨域
- CORS才是解决跨域的真正解决方案
- 前端无需做任何事情,正常发送Ajax请求即可
- 后端需要加响应头,或者使用第三方模块cors
3.ES6模块化
- 模块化的好处
- 模块化可以避免命名冲突的问题
- 大家都遵守同样的模块化规范写代码,降低了沟通的成本,极大方便了各个模块之间的相互调用
- 只需关心当前模块本身的功能开发,需要其他模块的支持时,在模块内调用目标模块即可
3.1在nodejs中使用es6模块
- 确保安装了 v13.0.0或更高版本的 node.js
- 在 package.json 的根节点中添加 ==“type”: “module” ==节点
3.1.1导入导出方法1
- 导出方法1:import obj from ’ ./ .js’
- 导入方法1:export default{ }
- 导入方法中的路径前缀后缀都要写
- 这种方法导出的数据在导入时不能解构
3.1.2导入导出方法2
- 导出方法1:import {a,b,fn1} from ’ ./ .js’
- 导入方法2:export let a= ;export let b= ;
- export + 变量定义导出的数据,必须解构
- fn1 as f,把函数名fn2改为f
3.1.3导入导出方法3
- 第三种导入导出使用的是逻辑而不是导出的对象
- 直接用import导出
4.Promise
- 回调地狱:如果我们希望几个异步请求按照顺序来执行,那么就需要将这些异步操作嵌套起来,嵌套的层数特别多,就会形成回调地狱 或者叫做 横向金字塔
4.1Promise语法
- Promise对象可以解决回调地狱的问题
- Promise 是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理和更强大
- Promise可以理解为一个容器,里面可以编写异步程序的代码
- 从语法上说,Promise 是一个对象,使用的使用需要 new
- 使用:
import fs from 'fs';
let p = new Promise((resolve,reject) => {
fs.readFile('./txt/a.txt','utf8',(err,data) => {
if(err == null){
resolve(data);
}else{
reject(err);
};
});
});
p.then(function (results){
console.log(results)
},function(err){
console.log('异步操作失败,原因是:' + err.message);
});
p.then(function(results){
console.log(results);
}).catch(function(err){
console.log(err);
});
import fs from 'fs';
let p1 = new Promise((resolve,reject) => {
fs.readFile('./txt/a.txt','utf8',(err,data) => {
resolve(data);
});
});
let p2 = new Promise((resolve,reject) => {
fs.readFile('./txt/b.txt','utf8',(err,data) => {
resolve(data);
});
});
let p3 = new Promise((resolve,reject) => {
fs.readFile('./txt/c.txt','utf8',(err,data) => {
resolve(data);
});
});
p1.then(res => {
console.log(res);
return p2;
}).then(res => {
console.log(res);
return p3;
}).then(res => {
console.log(res);
});
- then()默认返回一个Promise对象,我们可以执行一个返回值,让下一次的then(),由这个返回值执行
- Promise将回调地狱变为链式编程
- Promise对象封装:
import fs from 'fs';
function getProObj(url){
return new Promise((resolve,reject) => {
fs.readFile(url,'utf8',(err,data) => {
resolve(data);
});
});
};
getProObj('./txt/a.txt').then((res) => {
console.log(res);
return getProObj('./txt/b.txt');
}).then((res) => {
console.log(res);
return getProObj('./txt/c.txt');
}).then((res) => {
console.log(res);
});
- 实际工作中,会有好多的框架,直接返回Promise对象,例如axios.js
4.2then-fs模块
- fs是内置模块/核心模块
- then-fs是第三方模块,需要下载使用,支持Promise对象开发
- 演示then-fs:
import fs from 'fs';
let p1 = fs.readFile('./txt/a.txt','utf8',() => {});
console.log(p1);
import thenFs from 'then-fs';
let p2 = thenFs.readFile('./txt/a.txt');
console.log(p2);
import thenFs from 'then-fs';
thenFs.readFile('./txt/a.txt','utf8').then(res => {
console.log(res);
return thenFs.readFile('./txt/b.txt','utf8')
}).then(res => {
console.log(res);
return thenFs.readFile('./txt/c.txt','utf8')
}).then(res => {
console.log(res);
});
- 以后记住,尽量多的使用支持Promise对象开发的模块; axios.js then-fs mysql …
4.3async和await
4.3.1async关键字
- async 修饰的函数,总是返回一个 Promise 对象
- 函数内的返回值,将自动包装在** resolved 的 promise** 中
- 注意:用async修饰的函数,并不会真的变成异步函数;
- 代码:
async function fn(){
return '哈哈哈';
};
let a = fn();
console.log(a);
a.then(res => {
console.log(res);
})
console.log('我是最后一行');
4.3.2await关键字
- await只能出现在异步函数中
- await能停止代码执行,让后面的同步代码,先执行
- await后面跟随的是一个promise对象
- await返回的是: Promise对象中的then()中的回调函数中的参数res
- 代码:
async function getProObj(){
return '哈哈哈'
};
async function fn(){
let a = await getProObj();
console.log(a);
console.log('我是函数中的最后一行代码');
};
fn();
console.log('我是最后一行');
4.3.3async和await解决回调函数
import thenFs from 'then-fs';
async function fn(){
let t1 = await thenFs.readFile('./txt/a.txt','utf8');
console.log(t1);
let t2 = await thenFs.readFile('./txt/b.txt','utf8');
console.log(t2);
let t3 = await thenFs.readFile('./txt/c.txt','utf8');
console.log(t3);
};
fn();
- try,尝试执行某些代码
- try中出现异常的对象,会赋值到e这个形参中
- **try…catch…**可以处理异步的异常
5.宏任务、微任务、事件循环
- JavaScript是单线程的,也就是说,同一个时刻,JavaScript只能执行一个任务,其他任务只能等待
- 同步任务:同步任务不需要进行等待可立即看到执行结果,比如console
- 异步任务:异步任务需要等待一定的时候才能看到结果,比如setTimeout、网络请求
- 执行机制:
- js代码开始执行后,主线程执行栈中会把任务分为两类
- 一类是同步任务, 一类是异步任务; 主线程执行栈优先执行同步任务
- 异步任务会被放入特定的处理程序中,满足条件后,被放到消息(任务/事件)队列中
- 主线程执行栈中所有的同步任务执行完毕之后,通过事件循环去消息(任务/事件)队列中
- 挑选优先满足条件的程序,放入主线程执行栈中执行。事件循环,周而复始,一直执行
- 面试题:
setTimeout(() => {
console.log('1')
}, 0);
console.log('2');
new Promise((resolve) => {
console.log('3');
resolve()
}).then(() => {
console.log('4');
}).then(()=>{
console.log('5')
});
console.log('6')