web服务器

web服务器

1.服务器的相关概念

1.1服务器与客户端

服务器的概念:提供网络服务的一台机器,通过在自己的电脑上安装特殊的软件(或者是运行某段特殊的代码)来提供服务

  • 服务器 = 电脑 + 可以给其他电脑提供服务的软件

  • 服务器:提供服务的是服务器

  • 客户端 = 电脑 + 软件(平时个人使用的软件)

  • 客户端:享受服务的是客户端

1.2服务器的类型

根据服务不同,服务器的类型也不同:

  • web服务器:安装apache, tomcat, iis, 或者在 node.js 环境写代码 来提供:图片浏览,新闻浏览…等服务的服务器。
  • ftp服务器:安装serv-U软件,为其它电脑提供文件下载,共享服务。
  • 数据库服务器:安装mysql软件,为其它电脑提供数据库服务。

1.3web服务器

  • 用户通过浏览器来享受web服务器提供的服务
  • 我们用url地址来访问某个web服务器上的资源
  • 浏览器端发起请求,web服务器收到请求后,响应这请求,并将处理结果返回给浏览器
  • 浏览器端与web服务器是通过http(或者是https)协议来进行请求和响应的

在这里插入图片描述

1.4IP地址

全称:I ntternet P rotocol Address

作用:标识一个网络设备在某个具体的网络当中的地址。我们要想访问某个电脑上的资源,首先要找到它对应的IP

分类:IPV4 IPV6

格式:**[0255].[0255].[0255].[0255] ** 例如ipv4:127.0.0.1 (这个地址是本机的ip地址)

即四个0~255的数字组成(在同一个网络中,计算机的IP地址是不允许重复的,都是唯一的)

1.5域名

域名:ip地址的别名,由于ip地址不好记忆,就取了一个好记的别名。

localhost这个域名特指127.0.0.1这IP地址。

localhost = 127.0.0.1 (一样,都表示本机的地址,只是换了一个好记的名称)

域名解析系统:把域名翻译成IP地址的系统

1.6端口

一个IP地址可以有65536个端口(范围是从[0,65535])。

不同的端口被不同的软件占用,以提供不同的服务。

一台电脑可以通过安装多个服务器端软件来提供服务,比如web服务器,ftp服务器…。

仅仅通过ip地址是无法区分不同的服务的,所有需要 IP地址 + 端口号 来区分不同的服务

在这里插入图片描述

  1. 服务器要提供服务必须通过指定的端口
  2. 服务器与客户端都需要通过端口进行通信
  3. 端口是可以编程分配的
  4. 有一些端口是被约定的了

可以通过 小黑窗输入命令: netstat -a -n -o 查看端口的使用情况

在这里插入图片描述

1.7协议(http)

制定客户端与服务器之间的通讯规则。不同的协议的作用也不同。

http协议

  • HTTP(HyperText Transfer Protocol)是超文本传输协议

  • 协议双方:浏览器与web服务器都要遵守的协议

  • 请求通常是由浏览器发起的

  • HTTP协议中明确规定了 请求数据响应数据 的格式(报文)

    • 浏览器 请求 资源 要遵守http协议:请求报文 (请求行,请求头,请求体)

    • 浏览器 返回 资源 要遵守http协议:响应报文 (响应行,响应头,响应体)

2.用http模块写一个简单的web服务器

2.1用http实现一个简单的虚拟服务器(效果如下)

// 1.引入 http 模块
const http = require('http');
// console.log(http);

// 2.创建服务// request:本次请求// res : 本次响应
const server = http.createServer((req,res)=>{
    // 回调函数 : 每一次收到请求,他就执行一次
    // 设置响应体
    res.setHeader('content-type','text/html;charset=utf-8')
    // 结束本次请求
    // 设置响应体:返回给用户看的
    res.end('你好,虚拟服务器完成');
});

// 3.启动服务
server.listen(8000,()=>{
    console.log('虚拟服务器启动成功','端口是8000');
});

运行结果:

在这里插入图片描述

2.2操作步骤

  1. 创建一个文件,名为 http模块实现虚拟服务器.js的文件(文件名路径可以自行设置,建议不要使用中文命名,这里为了演试就用中文的名字)。

  2. 在js文件中写入如下(如上图效果图)

    • 1)引入http核心模块
    • 2)使用createServer来创建服务
    • 3)使用listener来启动服务
  3. 运行js代码

    在js文件目录,打开小黑窗,键入命令 node http.js,此时会弹出一个小黑窗,不要关。

  4. 本地验收

    打开一个浏览器页面,输入’http://localhost:8000’,观察效果:

  5. 共享地址

    localhost改成你自己电脑的ip地址,再把这个路径发你的朋友(同一个局域网)来访问。

  6. 停止服务( ctrl + c )

2.3工作原理

使用http模块在本机中创建一个虚拟的服务器,用来接收浏览器的请求,并给出响应

在这里插入图片描述

注意:小黑窗不要关,它就是服务器,它不会有主动行为(看起来没有任何变化),它在时刻等待客户端的访问。

2.4代码解析

  1. 引入核心模块,得到的http是一个对象。

  2. http.createServer方法创建一个http服务。

    参数是一个回调函数:当有http请求进来时,它会自动被调用。请求一次,它就被调用一次

    第一个参数:客户端的请求

    第二个参数:设置对本次请求的响应

    res.end() :设置响应体,结束请求。

  3. server.listen() 用来监听端口。

    格式:server.listen(端口号,[回调函数])。回调是可选的。

    说明:

    • 如果监听成功,则回调函数会执行一次。

    • 如果不成功(例如端口被占用),会报错。

在这里插入图片描述

2.5修改代码之后要重启服务器

更改res.end()的内容,重启后,再次观察

  • 停止服务: 在小黑窗中按下ctrl+c 停止服务。
  • 重启服务:就是重新运行程序(按下向上的箭头,再回车)。

3.理解请求与响应

3.1请求

当web服务器就绪之后,如果没有客户端来访问,它是不会有任何效果的。那么回调函数就不会被执行了。

然而每一次的请求,都会导致回调函数要执行一次。

3.2服务器的响应内容格式

res.end()的格式只能是 stringbuffer

4.根据不同的url返回不同的内容-认识URL

4.1URL全称

Uniform Resource Locator,统一资源定位符。

4.2作用

定位资源

4.3格式

协议://主机地址[:端口]/路径?查询字符串#锚点

  • 协议:http 或者是 https

  • 主机地址:IP地址 或者 域名

  • 端口号:

    • http请求,默认端口80(可以省略)

    • https请求,默认端口443(可以省略)

    • MySQL默认端口3306

  • 路径:服务器文件夹上的资源。(.html/.css/.images/.js/接口)

  • 查询字符串(参数):? 后面的部分,是键值对的形式

  • 锚点:网页内部的锚点链接

5.不同的URL返回不同的内容-req.url

5.1目标:

通过 req.url来获取当前请求的url地址 ,并做出相应处理

5.2req.url 用来获取本次请求的资源地址。

//引入http模块
const http = require('http');

// 创建服务
const server = http.createServer(function(req, res) {
  console.log(req.url)
  res.end(req.url)
});
// 启动服务
server.listen(8081, function() {
  console.log('success');
});

req.url一定是以**/**开头的。

在现代浏览器中,它们会自动去请求服务器上的favicon.ico(先不用理这个)

6.不同的URL返回不同的内容-读取文件内容并返回

6.1目标

用户在访问服务器上不同的url时,能返回不同的内容

目录结构

|-index.html
|-style.css
|-01.png
|-js/jquery.js
|-server.js

请求与响应的对应的关系

用户的请求地址服务器的动作
http://localhost:8000读出index.html的内容并返回
http://localhost:8000/index.html读出index.html的内容并返回
http://localhost:8000/style.css读出style.css的内容并返回
http://localhost:8000/01.png读出01.png的内容并返回
http://localhost:8000/js/jquery.js读出jquery.js的内容并返回
http://localhost:8000/xxxx 或者不是上面的地址返回404

代码示例:

// 1.引入 http 模块
const http = require('http');
// console.log(http);
const fs = require('fs')
const path = require('path')
// 2.创建服务
// request:本次请求
// res : 本次响应
const server = http.createServer((req,res)=>{
    // 回调函数 : 每一次收到请求,他就执行一次

    // 读出文件
    // fs.readFile('')
    const {url} = req;
    console.log(url);    
    if(url === '/' || url === '/index.html'){
        const pathFile = path.join(__dirname,'index.html');
        // console.log(pathFile);
        // 同步读取文件
        const content = fs.readFileSync(pathFile,'utf8');
        // console.log(a);
        // 结束请求
        res.end(content)
    } else if(url === '/style.css'){
        const pathFile = path.join(__dirname,'style.css');
        // console.log(pathFile);
        // 同步读取文件
        const content = fs.readFileSync(pathFile,'utf8');
        // console.log(a);
        // 结束请求
        res.end(content)
    }
   else if(url === '/01.jpg'){

        const pathFile = path.join(__dirname,'01.jpg');
        console.log(pathFile);
        // 同步读取文件
        const content = fs.readFileSync(pathFile);
        
        console.log(content);
        // console.log(content);
        // 结束请求
        res.end(content)
    }
   else if(url === '/js/jQuery.js'){

        const pathFile = path.join(__dirname,url);
        console.log(pathFile);
        // 同步读取文件
        const content = fs.readFileSync(pathFile);
    res.setHeader('content-type','text/html;charset=utf-8')
        
        console.log(content);
        // console.log(content);
        // 结束请求
        res.end(content)
    }
    else{
        res.end('ok')
    }

   
});

// 3.启动服务
server.listen(8000,()=>{
    console.log('服务器启动成功');
})

6.2什么是静态资源

静态资源指的是html文件中链接的外部资源,如.html, css、js、image文件等等),服务器的处理方法就是:读出文件内容,返回给用户。

7.不同的URL返回不同的内容-设置content-type

7.1目标

会根据不同的文件类型来设置不同的content-type

7.2content-type的作用

在http协议中,content-type用来告诉对方本次传输的数据的类型是什么。

  • 在请求头中设置content-type来告诉服务器,本次请求携带的数据是什么类型的
  • 在响应头中设置content-type来告诉服务器,本次返回的数据是什么类型的

通过使用res对象中的setHeader方法,我们可以设置content-type这个响应头。这个响应头的作用是告诉浏览器,本次响应的内容是什么格式的内容,以方便浏览器进行处理。

7.3常见的几种文件类型及content-type

  • .html:res.setHeader('content-type', 'text/html;charset=utf8')
  • .css:res.setHeader('content-type', 'text/css;charset=utf8')
  • .js:res.setHeader('content-type', 'application/javascript')
  • .png:res.setHeader('content-type', 'image/png')
  • json数据:res.setHeader('content-type', 'application/json;charset=utf-8')

其它类型,参考这里:https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types

7.4代码示例:

目录结构:

|--pubic
|-public/index.html
|-public/stye.css
|-public/1.png
|-server.js
// 1.引入http模块
const http = require('http');
// console.log(http); //输出的一个对象

const path = require('path');

const fs = require('fs');

// - .html:` res.setHeader('content-type', 'text/html;charset=utf8') `
// - .css:`res.setHeader('content-type', 'text/css;charset=utf8')`
// - .js:`res.setHeader('content-type', 'application/javascript') `
// - .png:`res.setHeader('content-type', 'image/png')`
// - json数据:`res.setHeader('content-type', 'application/json;charset=utf-8')`

// 2.创建服务
const server = http.createServer((req, res) => {

    // 解构赋值
    const { url } = req;
    // console.log(url);

    // 获取路径
    const pathFile = path.join(__dirname, 'public', url);
    // console.log(pathFile);

    // 获取后缀名
    const ext = path.extname(pathFile);
    // console.log(ext);
    try {
        if (ext === '.html') {
            res.setHeader('content-type', 'text/html;charset=utf-8')
            const conter = fs.readFileSync(pathFile);
            res.end(conter);
        }else if(ext === '.css'){
            res.setHeader('content-type', 'text/css;charset=utf-8')
            const conter = fs.readFileSync(pathFile);
            res.end(conter);
        }
        else if(ext === '.js'){
            res.setHeader('content-type', 'application/javascript')
            const conter = fs.readFileSync(pathFile);
            res.end(conter);
        }
        else if(ext === '.jpg'){
            res.setHeader('content-type', 'image/jpg')
            const conter = fs.readFileSync(pathFile);
            res.end(conter);
        }
        else{
            res.end('404');
        }
    } catch (err) {
        res.statusCode = 404;
        res.end("请求不到数据", '404')
    }
});

// 3.启动服务
server.listen(8000, () => {
    console.log('启动服务器成功', '端口号', 8000);
});

8.不同的URL返回不同的内容-设置statusCode

在这里插入图片描述

代码演示:

res.statusCode = 404;
res.end("请求不到数据", '404')

9.处理.html文件的二次请求

从服务器获取html文件之后,如果这个html文件中还引用了其它的外部资源(图片,样式文件等),则浏览器会重新再发请求。

假设在index.html中还引入了 style.css 1.png 或者 .js文件,则:浏览器请求localhost:8000/index.html之后,得到的从服务器反馈的内容,解析的过程中还发现有外部的资源,所以浏览器会再次发出第二次请求,再去请求相应的资源。

10.统一处理静态资源

文件目录:

|-public
|-public/index.html
|-public/stye.css
|-public/1.png
|-server.js

代码演示:

// 1.引入 http 模块
const http = require('http');
// 引入模块
const fs = require('fs');
const path = require('path');
// console.log(http);

const extToContentType = {
    '.html': 'text/html;charset=utf-8',
    '.css': 'text/css;charset=utf-8',
    '.js': 'application/javascript',
    '.jpg': 'image/jpg',
}


// 2.创建服务
// request:本次请求
// res : 本次响应
const server = http.createServer((req, res) => {
    // 回调函数 : 每一次收到请求,他就执行一次
    // const { url } = req;
    // console.log(url);
    // const pathFile = path.join(__dirname, 'public-content-type', url);
    // console.log(pathFile);
    // const conter = fs.readFileSync()

    // 解构赋值
    const { url } = req;
    // console.log(url);

    // 获取路径
    const pathFile = path.join(__dirname, 'public', url);
    // console.log(pathFile);

    // 获取后缀名
    const ext = path.extname(pathFile);
    // console.log(ext);
    if (extToContentType[ext]) {
        // const conter = fs.readFileSync(pathFile);
        res.setHeader('content-type', extToContentType[ext])
        res.end(conter);
    } else {
        res.statusCode = 404;
        res.end("请求不到数据", '404')
    }
});

// 3.启动服务
server.listen(8001, () => {
    console.log('服务器启动成功');
})

11.理解静态资源与接口的区别

服务器上有很多的资源,每个资源都有自己的url。客户端浏览器想要访问某个资源就要向服务器发起对应的请求。

11.1资源的分类

  • 静态资源
    • 它们一般表现为一个一个的文件。例如index.html, style.css, index.js, mp4, .png…。
    • 处理请求静态资源时,服务器一般就直接读出资源的内容,再返回给客户端浏览器
  • 动态资源:接口
    • 它们不是以某个具体的文件存在的,而是服务器上的一段代码,访问接口时,服务器会执行这段代码,然后把代码的执行结果返回给客户端浏览器。

11.2发送请求的途径

  • 在地址栏中直接访问这个url
  • 通过某个a标签进行进行跳转
  • 通过表单进行提交
  • 通过ajax技术访问这个url

11.3发送请求的类型

  • get:在地址栏中直接访问这个url就是get方式。对于静态资源,我们通过的处理方式就是get请求。
  • post: 通过表单提交,可以设置form的method为post
  • delete
  • put
  • patch
  • options

12.写一个不带任何参数的get类型接口

12.1目标

提供一个名为getList的接口(http://localhost:8083/getList),它以json字符串格式返回db/data.json的内容。

12.2目录结构

|-db
|---data.json # 数据
|-server.js # 你的代码

12.3代码演示

// 三要素
// 1.引入 http 模块
const http = require('http');
// console.log(http);
const path = require('path');
// 引入模块
const fs = require('fs');
// 2.创建服务
// request:本次请求
// res : 本次响应
const server = http.createServer((req, res) => {
    // 回调函数 : 每一次收到请求,他就执行一次
    // 1. 当你的请求是get类型,并且地址是/getList时,解析查询字符串
    // 设置响应体
    // res.setHeader('content-type','text/html;charset=utf-8')
    const { url, method } = req;
    console.log(url, method);
    if (url === "/getList" && method === "GET") {
        const pathFile = path.join(__dirname, "db", 'data.json');
        console.log(pathFile);
        res.setHeader('content-type','application/json;charset=utf8')
        const conter = fs.readFileSync(pathFile)
        res.end(conter);
    } else {
        res.statusCode = 404;
        res.end("404")
    }
});

// 3.启动服务
server.listen(8452, () => {
    console.log('服务器启动成功');
});

注意:类型

  • req.method 可以判断请求的类型
  • res.end()的参数只能是字符串(或者是buffer),而不能是对象

13.写一个不带任何参数的get类型接口

13.1目标

提供一个名为getList?name=abc的接口(http://localhost:8083/getList?name=abc),它以json字符串格式返回db/data.json的内容。

13.2目录结构

|-db
|---data.json # 数据
|-server.js # 你的代码

13.3代码演示:

// 1.引入 http 模块
const http = require('http');
// console.log(http);
// 引入模块
const fs = require('fs');
const path = require('path');
const ps = require("querystring");

// 2.创建服务
// request:本次请求
// res : 本次响应
const server = http.createServer((req, res) => {
    // 回调函数 : 每一次收到请求,他就执行一次
    const [url, queryStr] = req.url.split("?");

    if (url === "/getList" && req.method === "GET") {
        const qsObj = ps.parse(queryStr)
        console.log(qsObj);
        const pathFile = path.join(__dirname, "db", "data.json")
        res.setHeader('content-type', 'application/json;charset=utf8')
        const conter = fs.readFileSync(pathFile)
        const arr = JSON.parse(conter)
        const re = arr.find(function (item) {
            if(item.name === qsObj.name){
                return true;
            }else{
                return false;
            }
        })
        const resa = JSON.stringify(re)
        console.log(resa);
        res.end(resa)
    } else {
        res.end('你好');
    }
    // 结束本次请求
    // 设置响应体:返回给用户看的
});
// 3.启动服务
server.listen(8004, () => {
    console.log('服务器启动成功');

})
  • 12
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力活着吧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值