服务器
B/S架构:Browser(浏览器)/Server(服务器)C/S架构:Client(客户端)/Server(服务器)
网络协议
网络协议,是指计算机为了能够在网络中进行数据的交换。从而去建立的一个规则、标准TCP/IP协议
TCP/IP协议,称为网络通讯协议,是互联网中最基本的协议。TCO/IP协议是一个协议簇,在该协议下还包含了很多的小协议:
http(s):
TCP:
IP:
DNS:
...
在浏览器中输入url发生了什么
1.域名解析
域名就是我们平常所说的网址,'https://www.baidu.com' 中的www.baidu.com 就是百度的域名。真正访问一个计算机是通过该计算机的IP地址去进行访问,但是由于IP地址不好记,用户体验不好,所以就出现“域名”。
域名解析,指的是通过DNS服务器(域名解析服务器)对域名进行解析,找到该域名所对应的IP地址。
2.建立TCP连接
TCP(传输控制协议)用于保证计算机之间数据传递的完整性和安全性。三次握手
TCP协议通过三次握手来保证数据传递的完整性和安全性。
三次握手的目的是为了确保客户端和服务端都处于正常工作的状态。
3.客户端发送请求、服务端处理请求
TCP连接建立成功后,浏览器就可以利用HTTP协议向服务器发送请求了。服务器接收到请求后,开始处理请求,处理完成后,服务器将处理结果返回(响应)给客户端。
4.关闭TCP连接
客户端接收到服务端发送的数据后,需要通过TCP协议来断开与服务器的连接。四次挥手
浏览器渲染页面
浏览器接收到服务器响应的数据后,开始对数据进行解析并渲染。Nodejs
Node.js是一个基于Chrome V8 引擎的JavaScript运行时。JavaScript运行时:JS代码的运行环境。
Chrome V8 引擎
浏览器内核:主要分为渲染引擎和js引擎。
渲染引擎:负责解析编译HTML和CSS代码。
JS引擎:负责解析编译js代码。
V8引擎是谷歌公司开发的一款js引擎,是目前公认的解析js代码最快的引擎。
Node.js让JavaScript代码可以在服务端运行。
命令行工具的基础命令
cd:进入某个文件夹。cd后面可以跟一个路径(建议直接拖文件夹)
cd后面还可以跟一个文件夹名(该文件夹必须是当前路径的子文件夹)
cd .. :返回上一级目录
模块化
每一个js文件都是一个独立的模块,模块与模块之间,是没有关系的。默认情况下模块之间不能进行数据交换。以前模块化是后端的一种概念,前端是没有模块化的.从ES6开始,前端也引入了模块化的概念。
前端模块化
引入js
引入:引入其他模块中所暴露的数据。在html中引入js:需要添加一个type=module属性
<script src="./index.js" type="module"></script>
在js中引入js:一个模块中加载另一个模块 import '相对路径'
import './js/a.js';
import './js/b.js';
暴露
暴露:将模块内的数据暴露出去,供其他模块使用。1.暴露export default(一个模块里只能使用一次)
function foo() {console.log('foo')}
export default {a:1,foo:};
引入import变量名from './a.js'
import bojA from './a.js';
console.log(objA.a);
objA.foo();
2.暴露export
export var a = 1;
export function foo(){
console.log('hello foo');
}
引入import {对应的变量名} from '相对路径'
import {a,foo} from './a.js';
后端模块化
commomjsECMAScript是一种规范,JavaScript是这个规范的实现。
CommonJS是一种规范,Nodejs是这个规范的实现。
在JS中引入JS
require('./b.js');
暴露和引入
暴露
module.exports.num = 10;
module.exports ={num:10};
引入
const aJS = require('./a.js');
const { num } = require('./a.js');
注意:
1.当使用require去加载某个模块时,除了第一次加载会运行该文件以外(第一次运行完成后会进行缓存),后续的加载都会从缓存中读取该文件。换句话说,同一个文件被require多次,只会执行一次。
2.require中的js文件后缀名可以省略。
3.require中的路径,如果只有模块名,那就说明引入的是第三方下载的模块或者是Nodejs原生自带的模块。
练习
// const student = {
// name:'zs',
// age:'20',
// sex:'nv'
// }
//ES6 解构赋值
//解构:保持等号左右两侧的结构(数据类型)一致
// const {name:a,sex:c,age:b} = student;
// console.log(a,b,c);
// console.log(student.name,student.age,student.sex);
//ES6 中关于对象属性的简写,当属性名和属性值是同一个单词时,冒号和其中一个单词可以省略
//ES6中关于对象方法的简写,可以将冒号和function省略
// const age = 20;
// const student = {
// name:'zs',
// age,
// sex:'nv'
// }
// console.log(student); //{name:'sz',age:20,sex:'nv'}
// const student = {
// name:'zs',
// age:'20',
// sex:'nv'
// }
//将student的引用地址赋值给了student1
// const student1 = student;
// const student2 = {...student};
// console.log(student==student1); //true
// console.log(student==student2); //false
// const student = {
// name:'zs',
// age:'20',
// sex:'nv'
// }
// const student1 = {
// ...student,
// age:'30'
// }
// console.log(student1); //age值改为30
异步
同步和异步
同步:在同一个时间段内,只能做一件事情;异步:在同一个时间段内,可以同时做多件事情;
JavaScript是一个单线程语言。
console.log('同步1');
setInterval(() => {
console.log('异步1');
},1000);
console.log('同步2');
console.log('同步3');
setInterval(() => {
console.log('异步2');
},500);
console.log('同步4');
console.log('同步5');
/*
同步1
同步2
同步3
同步4
同步5
异步2
异步1
异步2
异步2
异步1
异步2
*/
AJAX(特点)
可以实现与服务器的异步通信。局部刷新页面。
异步解决方案的发展
回调函数Promise(ES6)
generator(ES6)
async/await(ES7):异步的终极解决方案
Promise
用于方便进行异步操作的回调函数var promise = new Promise(function (resolve, reject) {
//定义了一个变量promise,是构造函数Promise的一个实例,Promise接受两个参数,第一个是resolve,第二个是reject。
setTimeout(resolve,1000)
})
promise
.then(
function () {
console.log(1)
return promise
}
)
//实例化的对象(在这里也就是指promise)的then方法接受两个函数为参数,上面的代码中,then里面的function部分,就是promise接受的第一个函数。
//then方法接收的第一个函数:resolve
//then方法的第二个参数:rejecte函数
function fn() {
return new Promise(resolve => {
setTimeout(resolve,1000)
})
}
fn().then(function () {
console.log(1)
return fn()
}).then(function () {
console.log(2)
return fn()
})
//
async/await
async:用于定义一个异步函数,异步函数的返回值是一个promise对象。async function foo(){
}
foo();
await:一般用于等待一个promise对象,实际上就是等待一个异步处理结果。
const p = new Promise((resolve,reject) => {
resolve('1111111');
});
async function foo() {
const msg = await p;
console.log(msg);
}
foo(); //1111111
练习
// new Promise((resolve,reject) => {
// setTimeout(() => {
// console.log('1');
// resolve('hello');
// },10);
// console.log('2');
// resolve('world');
// }).then((data) => {
// console.log(data);
// })
//2 world 1
// async function main(){
// const data = await Promise.resolve('hello');
// console.log(data); //hello
// return data;
// }
// const data = main();
// console.log(data);
// //Promise { }
// //hello
// async function bar(){
// const num = 100;
// return num;
// }
// const barData = bar();
// console.log(barData);
// function foo(){
// const num = 100;
// return num;
// }
// const fooData = foo();
// console.log(fooData);
// Promise { 100 }
// 100
// function foo(){
// const num = 100;
// return num;
// }
// async function bar(){
// const data = await foo();
// console.log(data);
// }
// bar();
// console.log(200);
// 200
// 100
// function foo(){
// const num =100;
// return num;
// }
// async function bar(){
// console.log(300);
// const data = await foo();
// console.log(data);
// }
// bar();
// console.log(200);
// 300
// 200
// 100
// function foo(){
// console.log('1');
// return '2';
// }
// async function bar(){
// console.log('3');
// return Promise.resolve('4');
// }
// async function main(){
// console.log('5');
// const v1 = await foo();
// console.log(v1);
// const v2 = await bar();
// console.log(v2);
// }
// main();
// console.log('6');
//516234
// function foo(){
// console.log('1');
// return '2';
// }
// async function bar(){
// console.log('3');
// return Promise.resolve('4');
// }
// async function main(){
// console.log('5');
// const v1 = await foo();
// console.log(v1);
// const v2 = await bar();
// console.log(v2);
// }
// main();
// var promise = new Promise((resolve) => {
// console.log('7');
// resolve('8');
// });
// promise.then((val) => console.log(val));
// console.log('6');
// 51762384
node中文件操作
//引入文件系统模块
const fs = require('fs');
// //1.读取文件内容
// //异步
// fs.readFile('./tes.txt','utf-8',function(err,data) {
// console.log('err',err);
// console.log('data',data);
// });
//隐式转换
//0 '' underfined null NaN false 这六个转成布尔值都是false其他都是true
//同步先执行,异步后执行
//同步
// const result = fs.readFileSync('./tes.txt','utf-8');
// console.log('---------------------');
// console.log(result);
// try {
// const result = fs.readFileSync('./tes.txt','utf-8');
// console.log('success',result);
// } catch(error) {
// console.log('读取失败');
// }
//在文件中写入内容
//新内容会将就内容覆盖掉
//如果路径所对应的文件不存在的话,会自动创建该文件(不会自动创建文件夹)
//异步
// fs.writeFile('./tes.txt','new',function(err){
// if(err){
// console.log('写入失败');
// }else{
// console.log('写入成功');
// }
// });
//同步
// fs.writeFileSync('./tes.txt','new');
//3.往文件中追加内容
// fs.appendFile('./tes.txt','新追加',err => {
// if(err){
// console.log('失败',err);
// }else{
// console.log('success');
// }
// });
//4.复制文件内容
// fs.copyFile('旧文件路径','新文件路径',err =>{
// if(err){
// console.log('失败',err);
// }else{
// console.log('成功');
// }
// });
//5.删除文件
// fs.unlink('文件地址',err =>{
// if(err){
// console.log('失败',err);
// }else{
// console.log('成功');
// }
// });
//6.文件重命名
// fs.rename('./tex.txt','./test.txt',err => {
// if(err){
// console.log('失败',err);
// }else{
// console.log('success');
// }
// });
node中文件夹操作
//7.创建文件夹
// fs.mkdir('./public',err => { //创建同级public文件夹
// if(err){
// console.log('失败',err);
// }else{
// console.log('success');
// }
// })
//fs.mkdirSync();
//8.删除文件夹(只能删空的文件夹)
// fs.rmdir('./public',err => { //删除同级public文件夹
// if(err){
// console.log('失败',err);
// }else{
// console.log('success');
// }
// })
//9.读取文件夹内容
// fs.readdir('./public',(err,data) => {
// if(err){
// console.log('失败',err);
// }else{
// console.log('success',data);
// }
// })
//10.判断文件/文件夹是否存在
// fs.access('./public',err => {
// if(err){
// console.log('文件或文件夹不存在');
// }else{
// console.log('文佳或文件夹存在');
// }
// });
// fs.accessSync();
// fs.existsSync();
//11.查看文件(文件夹)状态,判断当前路径是文件还是文件夹
// fs.stat('./a',function(err,stats){
// if(err){
// console.log('失败',err);
// }else{
// const isfile = stats.isFile();
// const isDir = stats.isDirectory();
// console.log(isfile,isDir);
// }
// })
封装删除文件方法
const fs = require('fs');
function rmDir(dir){
//判断 dir是文件还是文件夹
const stats = fs.statSync(dir);
if(stats.isFile()){
//进入if,说明dir是文件,直接删除文件
fs.unlinkSync(dir);
console.log(dir+'删除成功');
}else{
//进入else,说明dir是文件夹
//读取文件夹中的内容
const files = fs.readdirSync(dir);
//清空文件夹的内容
files.forEach(item => {
//判断item是文件还是文件夹
//进入if,说明item是文件,直接删文件
//进入else,说明item是文件夹
//读取文件夹中的内容
rmDir(`${dir}/${item}`);
});
//删除空文件夹
fs.rmdirSync(dir);
console.log(dir+'文件夹删除成功');
}
}
rmDir('./data');
封装移动文件方法
function moveDir(oldDir,newDir){
try{
const isAccess = fs.accessSync(newDir);
}catch(error){
console.log(newDir+'路径不存在,重新输入');
const dirs = newDir.split('/');
const result = dirs.reduce(function(sum,item,index){
// console.log(sum);
if(index>1){
fs.mkdirSync(sum);
}
return sum+'/'+item;
});
fs.mkdirSync(result);
}
fs.renameSync(oldDir,`${newDir}/${oldDir}`);
}