Web应用

JS Web

Web 开发原理

  1. WEB 应用

    • 使用客户端访问服务器的形式。
    • 一個完整的 web 应用包含
      1. 客户端 (浏览器、移动设备)
      2. 服务端 (服务===>获取静态资源)
    • B|S 架构为基础
      • C|S 架构(基于网络应用、例如 QQ 、微信、只要装客服端的都是 C|S 架构,服务器会主动往客户端发送数据),弊端:必须下载客户端,就会占内存。
        1. _clent _ | server
        2. 客户端 | 服务器
      • B|S 架构 (不用下载客户端,输入一个网址,就返回一个页面、数据,处于安全考虑浏览器不会主动往客户端发送数据)。弊端: B|S 受限与浏览器本身,效果以及性能方面比不上 C|S 架构。
        1. brouser | server
        2. 浏览器 | 服务器
  2. web 应用的通信

    • 客户端发送一个请求到服务端,服务端接收到这个请求,做一个相应的处理,处理完成拿到一些数据,在将数据返回给客户端,就可以展示给用户看。
    • 浏览器向服务器发送请求,服务器接收请求后,响应并返回数据给浏览器。
    • Tcp/ip 协议(协议组)
      1. 应用层( HTTP 协议)
      2. 传输层( TCPUDP 协议)
      3. 网络层( ip
      4. 物理层( WiFi
    • 通过一层一层的封装、解析(类似于寄快递),计算机之间的通讯必须遵守Tcp|ip协议。
  3. http 协议

    • Web 通信依赖于 http 协议, 浏览器遵循这个 http 协议,后台就可以获取并解析。
    • Hyper Text Transfer Protocol(超文本传输协议)是用于从万维网( World Wide Web )服务器传输超文本到本地浏览器的传送协议。
    • HTTP 是一个基于 TCP/IP 通信协议来传递数据。
    • HTTP 是一个属于应用层的面向对象(属性和方法是面向对象的表现形式,单独的特性抽象出来)的协议。
  4. http 协议的特点

    • 超文本传输协议

      1. 建立链接
        • TCP 三次握手(保证数据的安全性)
          1. 浏览器先发送请求给服务器。
          2. 服务器收到请求发送回应给浏览器。
          3. 浏览器确认后,发送正式连接请求。
      2. 浏览器发送请求。
      3. 服务器处理请求并返回。
      4. 浏览器接收响应并展示到浏览器上。
      5. 断开连接。

      ​ 为了提高效率,使用常连接,不会每次请求都进行三次握手,而是可以设置一个时间,这个时间没有发送过这个请求才会断开连接。即使是常连接,他依旧是无状态。

    • 客户向服务器请求服务时,只需传送请求方法和路径。

    • 请求方法常用的有

      1. GET
      2. POST
      3. HEAD
      4. PUT
    • 每种方法规定了客户与服务器联系的类型不同。

    • 由于 HTTP协议简单,使得 HTTP 服务器的程序规模小,因而通信速度很快。

    • 基于请求/响应的模型。(浏览器发送请求,服务器处理请求并返回数据)

    • 无状态(服务器无法存储状态==>例如这次发送登录成功请求,下一次登录时,浏览器并不知道之前登录过,服务器始终认为这是一个新的连接)。

    • 无连接(访问一次,连接一次)。

    • 请求信息

      • 请求行

        1. 请求名
        2. 路径 ===> url (请求资源的地址)
        3. 请求方法( GET、POST
      • 请求头(浏览器告诉服务器的相关的配置信息===>_cookie、JSON_格式、压缩方式等…)

      • 空行

      • 请求消息体(参数,除了 get 提交以外,其他的参数都是放在请求消息体里, get 是路径里)

        GET请求
        /index.html?a=1&b=2
        
        注:
           在get请求里面参数是携带在/index.html后边,以问号开头a=1&b=2,解析时a=1&b=2为一个字符串,通过正则表达式,将a=1&b=2变成一个对象,a的属性为1,b的属性为2
        
         注: 
            GET 请求问号后面的为参数(相当于传了一个a=1和b=2的数据,传到后台,也称为请求的参数)
         
        举一个登录的例子
            要收集用户输入的的账户和密码 ,以GET的方式往后台传就可以写成 GET /index.html?username=zhangsan&password=111111 HTTP/1.1
        
    • 响应信息

      • 状态行
        1. 状态码
          • 100-199
          • 200-299(成功)
          • 300-399(资源被移走了之后的处理方法===>302重定向,304===>缓存)
          • 400-499(客户端错误,404===>访问不存在的页面,401===>权限不足)
          • 500-599(无服务端内部错误,503===>无服务崩了,500===>)
        2. 状态描述
      • 响应头(服务器告诉浏览器的相关的配置信息====>cookie、连接方式等…,这些信息不会展示到页面上)
      • 空行
      • 响应消息体(展示的页面的数据)

NodeJS

  1. 学习目标

    • 怎样在后台搭建一个服务器
    • 怎么完成数据持久化,等待访问
    • node 使前端从客户端过渡到服务端
    • 如何通过 node 搭建 web 应用。
  2. 概念

    • node 就是一个解析器,脱离浏览器,固 node 可以做服务器 即前端可以开发后端。
    • node 可搭建后台服务。
    • 基于 Chrome V8 引擎的 JavaScript 运行时。(可供 JS 运行的环境,脱离浏览器)
  3. 特点

    1. 基于事件驱动。(采用事件驱动的方式,处理异步操作。===>需要花费时间的操作,都丢到任务池)

    2. nodejs 是基于非阻塞式 io 的异步运行框架。

      • 同步
        • 来了一个顾客(一个请求),就分配一个服务员(内存空间),服务员将顾客点的菜交给后厨(后台),后厨开始做菜,厨房得把这个顾客点的菜做好了,交给服务员,服务员端给这个顾客,完成后才会招待下一位顾客。
        • 注:一个时间只有一个事情在做,完成后才可进入下一个事情下一个事情。
      • 异步
        • 来了一个顾客(一个请求),就分配一个服务员(内存空间),服务员将顾客点的菜交给后厨(后台),后厨开始做菜,此时服务员空闲了,可以招待下一位顾客,把下一个才告诉后厨
        • 注: 异步就可以做很多事情。
      • 进程
        • 启动一个程序 计算机里面就是启动了一个进程。(即:分配了一段内存空间,这个空间交给这一个程序进行执行。)
      • 线程
        • 在进程里面又可以把这个内存分成一块一块的,每一块来运行一个线程。
        • 注:没有进程,就不可能有线程。
      • 任务池
        • 放任务的(即异步的函数) 浏览器端的异步函数 。1、setTimeou 2、 setInterval 3、ajax 的回调
      • 阻塞式 IO(输入、输出)
        • 类似于同步。
      • 非阻塞式 IO(输入、输出)
        • 类似于异步。
    3. JS 就是通过非阻塞式 IO 实现异步操作。(任何需要花费时间的操作,都丢到任务池,同步代码执行完后,才执行任务池的代码)。

    4. 浏览器内核:

      1. 渲染引擎
        • webkit(起始于苹果公司)
        • cocko
        • Blink(基于 webkit
      2. js 引擎
        • V8Chrome
    5. 通过 async/await 异步做远程接口

      function promise(time) {
          return new Promise((resolve, reject) => {
              setTimeout(function () {
                  resolve(`暂停${time}毫秒`);
              }, time)
          });
      };
      async function times() {
          let rs = await promise(1000);
          console.log(1, rs);
          rs = await promise(2000);
          console.log(2, rs);
          rs = await promise(3000);
          console.log(3, rs);
          rs = await promise(4000);
          console.log(4, rs);
      };
      times();
      
      async function _asyncFn(){
          const data = await new Promise((resolve, reject) => {
              request({
                  type: "post",
                  url: "/users/one",
                  // success表示异步成功,所以就调用resolve方法
                  success: resolve
              });
          });
      console.log(data);
      

Express

  1. express 快速生成 Web 应用。
  2. 基于Nodejs的框架。
  3. 项目结构
    • npm
      • 是包的管理工具。
    • bin
      • 运行的文件===> “start”: “node ./bin/www” 使用 npm start 运行的就是 bin
    • _routes _
      • 路由===>请求以及分发,一个服务提供给浏览器很多的资源,每一个资源通过路由器进行分发,究竟是请求资源
        还是接口,由路由来分发
    • app.js
      • 项目的入口===>所有的应用程序都有一个入口
    • _public _
      • 静态资源的根目录===>存放静态资源,html 、js
    • package.json
      • 配置文件
    • node_modules
      • 第三方依赖===>放第三方安装的其他东西

模块化

  1. 模块

    • 将系统中的各种功能,用某种方式组织起来的一种架构模式。目的是降低功能之间的耦合度,提高重用性和扩展性。(一段代码的集合(一个文件就是一个模块,模块也是代码的集合))
  2. 模块化

    • 同一个应用有很多不同的功能,如果都将各个功能放在一起就会大大增加耦合度,可能修改一个功能,导致另一个功能受到影响,这时就要将一个一个功能封装成一个模块,然后就他导出,需要用到就引入这个模块。每个模块之间是互补干扰的就降低了耦合度,随用随调代码可以进行的重用。
  3. 模块化开发

    • 是为了解决功能之间的高耦合、低内聚和无重用的问题。
  4. 模块规范分类

    • CommonJS 规范(基于服务器的模块规范)
    • AMD 规范===> requireJS 异步的模块化定义(预加载、缺点===>预先加载所有模块,有些用不到的模块也会加载,就浪费资源)
    • CMD ==> AeaJS 公共的模块化定义(将各种模块化规范的优点集合起来 特点=>既有同步、也有异步)
    • UMD 联合(不算是一个规范,只是将其他规范结合在一起)。
    • ES6 ===>modure官方的模块化规范。
  5. 使用模块化的优点

    • 提高重用性
    • 代码的可用性变强(扩展性,灵活性)
    • 避免命名空间的污染()
    • 解决模块之间依赖性问题。(不用考虑加载顺序,例如C文件调用B文件,B文件调用A文件,A文件又调用B文件,引用顺序A==>B==>C。如果先引入C,因为C调用的B还没有读取,所以会报错,模块化的开发就可以解决这个问题。)
  6. ES6 模块化规范

    • 语法

      1. 导入模块( import
      2. 导出模块( export
    • 实例

      // 声明时导出
      export function f1(){
          console.log(11);
      };
      // 声明后导出
      function f2(){
          console.log(22);
      };
      
      export{f2}
      // 声明式默认导出
      export default function f3(){
          console.log(333);
      }
      // 声明后默认导出
      function f4(){
          console.log(22);
      };
      export{f4 as default}
      
      // 引入
      import {f1} from "引入文件地址";
      // 默认导出的引入不用结构
      import 自定义名称 from "引入文件地址";
      // JS以模块化引入type="module"
      <script type="module" src="./src/index.js"></script>
      

MongoDB

  1. 数据库的分类
    • 关系型数据库
      • 由表、行、字段组成( SQL 语言)
        1. mySQL
        2. Qraole
    • NOSQL 数据库
      • 文档型数据库( JSON MongoDB
      • 键值对数据库
      • 对象型数据库
  2. MongoDB
    • 本质上也是一个程序,也是一种服务器应用。
    • 操作
      1. Create
      2. Read
      3. Update
      4. Delete
    • 组成
      1. 集合
        • 类似于 JS 里的数组
      2. 文档
        • 一个文档就是一个 JSON 对象
        • 文档有一个唯一的标识===>下划线 _
      3. 字段
        • 字段就是 JSON 对象的属性

三层架构

  1. 表现层
    • 把数据呈现(例如路由器就在表现层里面)
  2. 业务层
    • 设计业务(提供服务===> service
  3. 持久层
    • 数据持久化(与数据库打交道)
    • DAO 对象
  • 完整流程
    • 从表现层===>业务层====>持久层===>数据库====>返回持久层===>返回业务层===>在到表现层。

单页应用

  • MPA 多页应用
  • SPA 单页应用===>(整个应用只有一个页面,利用 JSDOM 来完成节点的替换(进行页面间的跳转))
  • 单页开发的优点
    1. 提高体统的体验度。
    2. 减少了请求数(页面只有一个)
  • 单页开发的缺点
    1. 增加了开发和维护的难度,但是会涉及到大量节点的操作(可以用框架 vueReact 等框架解决)
  • 单页不等同于模块化,两者是不同的,但是两者相结合可以达到最好的效果。

多页开发,就会存在很多个html页面,每次加载,就会发送请求,然后刷新除一个新的页面,用户就会明显感受到卡顿,体验很不友好。

  • 单页开发实现页面之间的跳转

    • 因为只有一个页面,其他的都是 JS 文件,要实现页面间的跳转需借助前端路由,通过匹配不同的路径,利用 JSDOM 来完成节点的替换,从而动态的渲染不同的内容。
    • 因为是通过 hash 值的变化,并没有向浏览器发送请求,所以单页开发不仅仅在页面的交互是无刷新的,页面跳转也是无刷新的。
  • 前端路由的配置

    import Login from "./modules/users/login.js";
    import Reg from "./modules/users/reg.js";
    import Info from "./modules/info.js";
    import Students from "./routes/students.js";
    // 节点的替换
    var routes = {
        '/login': () => new Login({ el: "#app" }),
        '/reg': () => new Reg({ el: "#app" }),
        //后台页面
        '/info': {
            ...Students,
            //后台管理系统
            on: () => {
                new Info({
                    el: "#app"
                });
            },
        },
    };
    var router = Router(routes).configure({ recurse: "forward" });
    export default () => {
        router.init();
        // hash锚点,默认路径
        // 有路径就把路径传给location.hash,没有就用默认值
        location.hash = location.hash || "#login";
    }
    

前后端分离

  • 允许跨域访问的资源

    1. js
    2. css
    3. 图片
    4. link img scrtion 标签可以访问其他服务器上的资源(天生就能跨域,请求类型是 GET )
  • 不允许跨域访问的资源

    • ajax 请求(因为 ajax 操作可以对服务增删改查等…操作,所以是为了安全考虑。)
  • 什么是跨域?

    • 访问的内容,来自于两个不同的服务器( ip 、协议、端口任意一个不同)就会形参跨域。
  • 什么是同源?

    • 浏览器里面有一种安全策略(同源策略)
  • 为什么会形成跨域?

    • 跨域是同源导致的, 跨域是因为浏览器里面有一种安全策略(同源策略),由于同源策略导致ajax只能访问我的当前服务,要访问其他服务就形成了跨域(即=>我在一个服务器上边,想要请求其他服务器上的资源)
  • 怎样解决 ajax 的跨域访问?

    1. CORS

      • 是一个在服务器端设置一个响应头。(这个请求头允许其跨域)

      • app.js 中添加

        app.use('/*',function(req,res,next){
         res.setHeader("Access-Control-Allow-Origin","*");
         res.setHeader("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type,Accept"); // 服务器支持的头信息
         res.setHeader("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS"); // 允许的方法 
         next();
        })
        
      • 缺点===>需要修改服务器,带来隐患。

    2. JSONP (实际上是伪造 script 请求)

      • jsop 不是 ajax 技术,浏览器利用 script 标签,模拟发起一个请求跨域访问服务器,服务器把返回的数据,在外面包裹一个方法名称,浏览器接收到一个服务器返回的数据,执行他对应的函数,从而得到数据。

      • ajax 使用 JSONP

        ajax使用JSONP:
                    text({username,password}){
                         $.ajax({
                           url:"http://localhost:3001/users/login",
                           data:{username,password},
                           dataType:"jsonp",
                           success(data){
                                  consols.log(data)
                           }
                      })  
                    }
        注:请求时添加了一个 dataType:"jsonp"
        
      • JSONP 的缺点

        1. 使用jsop就意味着后台只能暴露 GET 请求。

        2. 后台返回的数据还得专门处理。

          处理返回的数据:
                 const {username,password,cbName}=req.query;
                 const data =await usersApi.login({username,password})
                 res.jsonp(data);
          
    3. 代理服务器(通过中间服务器转发)

      • 通过中间服务器来访问后端服务器的内容,从而实现浏览器的跨域访问。

      • 完成步骤

        1. 下载代理服务器插件

          npm install --save http-proxy-middleware
          
        2. 在中间服务器上配置代理,app.js中加入如下代码

          const {createProxyMiddleware } = require('http-proxy-middleware');
          const restream = function(proxyReq, req, res, options) {
           if (req.body) {
             let bodyData = JSON.stringify(req.body);
             // incase if content-type is application/x-www-form-urlencoded -> we need to change to application/json
             proxyReq.setHeader('Content-Type','application/json');
             proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData));
             // stream the content
             proxyReq.write(bodyData);
           }
          }
          const options = {
           target: 'http://localhost:3001', // 目标服务器的 host
           changeOrigin: true,        // 默认 false,是否需要改变原始主机头为目标 URL
           pathRewrite: {          // 重写请求
            '^/api': '/',          // 所有以 "/api" 开头的请求,"/api" 都会重写为 "/"
           },
           onProxyReq:restream
          }
          // 该行代码必须写在 var app = express(); 之后
          app.use('/api', createProxyMiddleware(options)); 
          
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值