服务器与客户端

284 阅读8分钟

服务器的类型

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

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

web服务器

  • 用户通过浏览器来享受web服务器提供的服务
  • 我们用url地址来访问某个web服务器上的资源
  • 浏览器端发起请求,web服务器收到请求后,响应这个请求,并将处理结果返回给浏览器

image.png 浏览器端与web服务器是通过http(或者是https)协议来进行请求和响应的

服务器相关概念-协议

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

http协议:

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

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

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

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

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

服务器相关概念-域名和IP

IP

全称:Internet Protocol Address。

作用:标识一个网络设备(计算机、手机、电视)在某一个具体的网络当中的地址。要访问某个电脑上的资源,先要找到它的ip。

分类:ipV4 ipV6

以ip4为例

格式:[0-255].[0-255].[0-255].[0-255] 即为四个 0-255 的数字组成。在同一个网络中,计算机的IP是不允许相同的,都是唯一的。

127.0.0.1 特指本机ip地址。

这个 http://220.181.38.149/ 会指向哪里?

域名

域名:ip地址的别名,由于ip地址不好记忆,我就给它们取个好记的别名。localhost这个域名特指127.0.0.1这个地址。

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

服务器相关概念-端口

一个IP地址的端口可以有65536个,范围是从[0,65535])。不同的端口被不同的软件占用,以提供不同的服务。

理解

如果理解IP地址(一台服务器)是一栋大商场,端口就是商场中的商铺的编号。

如果理解IP地址(一台服务器)是公司的前台电话,端口就是公司中各个部门的分机号。

一台电脑可以通过安装多个服务器端软件来提供服务,比如Web服务、FTP服务、SMTP服务等。显然,仅仅通过ip地址是无法区分不同的服务的,这里就需要用到 "IP地址+端口号"来区分不同的服务

image.png 0. 服务器要提供服务必须要通过指定的端口 0. 服务器与客户端都需要通过端口要进行通信 0. 端口是可以编程分配 0. 有一些端口号是被预定了的。

  • http: 80
  • https:443
  • mysql:3306

通过netstat -a -n -o 查看端口使用情况

服务器相关概念-URL

全称

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

作用

定位资源(css,html,js,png, avi,接口......)。

格式


协议://主机地址[:端口]/路径?查询字符串#锚点
  • 协议: http 或者是 https

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

  • 端口号

    • http请求,默认端口80(可以省略)
    • https请求,默认端口443(可以省略)
    • MySQL默认端口3306
  • 路径

    • 服务器文件夹上的资源。(.html/.css/.images/.js/接口)
  • 参数(查询字符串)

    • ? 后面的部分,是键值对的形式
  • 锚点

    • 网页内部的锚点链接

例如:itcast.cn:80/schools/stu…

经典用法:访问文件时传递参数。


// index.html
<a href='detail.html?id=1'>新闻1</a>
<a href='detail.html?id=2'>新闻2</a>

上面的两个地址在指向detail.html时,分别传入了不同的参数


// detail.html
<script>
// 1. 获取id
// 2. 根据id值去获取这个新闻的详情 
</script>

三步写一个简单的web服务器

第一步:新建一个文件,名为 d:/src/http.js( 文件名及路径名可以自行设置,建议均不使用中文字符), 内容如下

// 1. 引入http模块
const http = require('http');
​
// 2. 创建服务
const server = http.createServer(function(req, res) {
  console.log('有人来访问了')
  res.setHeader('content-type','text/html;charset=utf8')
  // 向客户端发送内容,并结束本次响应
  res.end('hello world');
});
// 3. 启动服务
server.listen(8081, function() {
  console.log('服务器启动成功,请在http://localhost:8081中访问....');
});

第三步:运行js代码。

在小黑窗中进入到d盘根目录,键入命令 node http.js,此时会弹出一个小黑窗,不要关。 第四步:本地验收

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


- 浏览器中的效果
- 小黑窗中的效果

第五步:共享地址

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

第六步:停止服务

ctrl + c

如果不能访问需要手动关闭电脑的防火墙,步骤如下图:

image.png

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

-   http.createServer方法创建一个http服务。参数是一个回调函数:当有http请求进来时,它会自动被调用。`请求一次,它就被调用一次`    -   第一个参数:`req, 客户端的请求`    -   第二个参数:`res,设置对本次请求的响应`    -   res.setHeader('content-type','text/html;charset=utf8')

        // 设置响应头

        // content-type 是键名。内容类型,

        // text/html;charset=utf8 是值

        // 告诉浏览器内容类型是html,编码格式是utf8

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

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

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

    -   说明:

        -   如果监听成功,则回调函数会执行一次。
        -   如果不成功(例如端口被占用),会报错。
        
         

 修改代码后要重启
 更改res.end()的内容,`重启`后,再次观察。

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

修改了服务器的代码要重启。

处理不同的请求--req.url

目标

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

req.url属性

首先就需要知道浏览器请求的url是什么。

涉及到和请求相关的信息,都是通过请求响应处理函数的第一个参数完成的。

代码示例

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用来获取本次请求的资源地址。在请求行中可以看到这一点。

常见的几种文件类型及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;charset=utf8')
  • .png:res.setHeader('content-type', 'image/png')
  • json数据:res.setHeader('content-type', 'application/json;charset=utf-8')

其它类型,参考这里:developer.mozilla.org/en-US/docs/…

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

二次请求

从服务器获取html文件之后,如果这个html文件中还引用了其它的外部资源(图片,样式文件等),则浏览器会重新再发请求。假设在index.html中还引入了 style.css 1.png 或者 .js文件,则:

  1. 浏览器请求localhost:8000/index.html之后,得到的从服务器响应的内容
  2. 解析的过程中还发现有外部的资源,所以浏览器会再次发出请求,再去请求相应的资源。

思路

一个最朴素的想法是枚举不同的请求来返回不同的文件。

代码


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        h1{
            text-align: center;
        }
    </style>
+    <link rel="stylesheet" href="./style.css">
</head>
<body>
    <h1>index.html</h1>
+    <img src="./1.png" alt="">
</body>
</html>

上面的+号只是表示这里的代码需要修改。


const http = require('http');
const fs = require('fs');
const path = require('path');
const app = http.createServer((req, res) => {
    const url = req.url // 获取本次请求的url
    console.log('用户请求的是',url)
​
    console.log(req)
    if(url === '/index.html') {
        // 读入index.html的内容,设置响应体
        fs.readFile('./static/index.html',(err,data)=>{
            res.setHeader('content-type', 'text/html;charset=utf8')
            console.log(data)
            res.end(data)
        })
    } else if(url === '/default.png'){
        // 读入 default.png 的内容,设置响应体
        fs.readFile('./static/default.png',(err,data)=>{
            // res.setHeader('content-type', 'text/css;charset=utf8')
            res.setHeader('content-type', 'image/png')
            console.log(data)
            res.end(data)
        })
    }else if(url === '/style.css'){
        // 读入 default.png 的内容,设置响应体
        fs.readFile('./static/style.css',(err,data)=>{
            res.setHeader('content-type', 'text/css;charset=utf8')
            res.end(data)
        })
    }else if(url === '/js/jquery.js'){
        // 读入 default.png 的内容,设置响应体
        fs.readFile('./static/js/jquery.js',(err,data)=>{
            res.setHeader('content-type', 'application/javascript;charset=utf8')
            console.log(data)
            res.end(data)
        })
    }else if(url === '/abc.jpg'){
        // 读入 default.png 的内容,设置响应体
        fs.readFile('./static/default.png',(err,data)=>{
            res.setHeader('content-type', 'image/png')
            console.log(data)
            res.end(data)
        })
    }else {
        res.statusCode = 404
        res.end('not found')
    }
})
//启动服务器,监听8082端口
app.listen(8082, () => {
  console.log('8082端口启动');
});

静态资源服务器

image.png

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

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

概念

静态资源:不会改变的资源。它们一般表现为某个文件。例如:index.html, style.css, index.js, mp4, .png....。处理请求静态资源时,服务器一般就直接读出资源的内容,再返回给客户端浏览器

接口: 它们不是以某个具体的文件存在的,而是服务器上的一段代码,访问接口时,服务器会执行这段代码,然后把代码的执行结果返回给客户端浏览器。

image.png

客户端发送请求的途径

  • 在地址栏中直接访问这个url

  • 通过某个a标签进行进行跳转

    
    <a href="要访问的url地址">文字</a>
    
  • 通过表单进行提交

    
    <form action="要提交的url的地址" method="get" target="_blank">
    </form>
    
  • 通过ajax技术访问这个url

    
    $.ajax({
      url: '要提交的url的地址',
      type:'get' // post, delete,put,
    })
    

发送请求的类型

  • get方式:

    • 在地址栏中直接访问
    • 或者是a标签的url
    • ajax的get方式
    • 通过表单提交,可以设置form的method设置为get
  • post方式:

    • 通过表单提交,可以设置form的method为post
    • ajax的post方式
  • delete

  • put

  • patch

  • options

  • ......