http 模块简介
HTTP 核心模块是 Node.js 网络的关键模块,用于创建 http 服务器,接受请求、响应内容
引入 http 模块
const http = require('http');
 
http.createServer()
 
- 使用 
http.createServer()可以创建新的服务器对象,即http.Server实例,接收一个事件处理函数作为参数 事件处理函数又接收req、res2 个对象参数,分别代表 [请求对象]、[响应对象]
const server = http.createServer((req, res) => {
    res.end('superman');
});
 
-  
事件处理函数
(req, res) => {}中的res是http.ServerResponse的实例 -  
在事件处理函数中,会调用
res.end()关闭响应响应结束后,服务器会将消息发送给客户端
必须在每个响应上调用它
 -  
若要在响应正文中发送数据给客户端,则使用
write()。 它会发送缓冲的数据到 HTTP 响应流 
const server = http.createServer((req, res) => {
    res.write('write');
    res.end('Superman');
});
 
 
getHeaderNames():获取已设置的 HTTP 消息头名称的列表getHeaders():获取已设置的 HTTP 消息头的副本setHeader('headername', value):设置 HTTP 消息头的值getHeader('headername'):获取已设置的 HTTP 消息头removeHeader('headername'):删除已设置的 HTTP 消息头hasHeader('headername'):如果响应已设置该消息头,则返回trueheadersSent():如果消息头已被发送给客户端,则返回true
const server = http.createServer((req, res) => {
    // 设置数据格式
    res.setHeader("content-type", "text/html; charset=utf-8");
    // 解决跨域问题
    res.setHeader("Access-Control-Allow-Origin", "*")
    // 设置接受的自定义请求头
    res.setHeader("Access-Control-Allow-Headers", "*")
    // ...
    res.end('superman');
});
 
Content-Type (内容类型),用于定义网络文件的类型和网页的编码,决定浏览器将以什么形式、什么编码读取这个文件
Content-Type 标头告诉客户端实际返回的数据类型。常见的 "content-type" 值:
媒体格式类型:
1. "text/html":HTML 格式
2. "text/plain":纯文本格式
3. "text/xml":XML 格式
4. "image/gif":gif 图片格式
5. "image/jpeg":jpg 图片格式
6. "image/png":png 图片格式
以 application 开头的媒体格式类型:
1. "application/json":JSON 数据格式
2. "application/xml":XML 数据格式
3. "application/xhtml+xml":XHTML 格式
4. "application/pdf":pdf 格式
5. "application/msword":Word 文档格式
6. "application/octet-stream":二进制流数据
7. "application/x-www-form-urlencoded":<form encType=""> 中默认的 encType,form 表单数据被编码为 key/value 格式发送    到服务器(表单默认的提交数据的格式)
另外一种常见的媒体格式是上传文件之时使用的:
1. "multipart/form-data":需要在表单中进行文件上传时,就需要使用该格式
- 编码可带可不带:"application/json; charset=utf-8"
- 值对大小写不敏感:"Application/JSON; charset=utf-8"
 
 
-  
close():停止服务器不再接受新的连接 -  
listen():启动 HTTP 服务器并监听连接 
server.listen(3030, _ => {
    console.log('http://127.0.0.1:3030');
});
 
response.writeHead()
 
在处理消息头之后,可通过 response.writeHead() 发送消息头给客户端
response.writeHead(statusCode[, statusMessage][, headers]):用于向请求发送响应头
statusCode:3 位的 HTTP 状态码- 给定人类可读的 
statusMessage作为第 2 个参数 headers:响应头。可以是 Array,其中键和值在同一个列表中,偶数偏移是键,奇数偏移是值
- 返回对 
http.ServerResponse的引用,以便可以链式调用 response.writeHead()方法只能调用一次,且必须在response.end()之前调用- 如果在调用 
response.writeHead()方法之前调用了response.write()/response.end()
会计算隐式 / 可变的标头,并调用response.writeHead() 
const http = require("http");
const server = http.createServer((req, res) => {
    const body = 'superman';
    res.writeHead(200, { // OK 请求成功
        'Content-Length': Buffer.byteLength(body), // Buffer 流的长度
        'Content-Type': 'text/plain' // 数据的格式
    }).end(body);
});
server.listen(3030, _ => {
    console.log('http://127.0.0.1:3030');
});
 
Content-Length 以字节为单位,而不是字符
 使用 Buffer.byteLength() 来确定正文的长度。Node.js 不会检查 Content-Length 和已经传输的正文的长度是否相等
-  
response.setHeader()设置的标头,会与response.writeHead()设置的标头合并
如果设置的内容一样,则response.writeHead()的优先级较高 -  
如果先调用
response.writeHead(),后调用response.setHeader()
则response.writeHead()会直接将提供的标头写入网络通道,且内部不缓存
在标头上response.getHeader()不会产生预期的结果如果需要逐步填充标头并在未来进行潜在的检索和修改,则改用
response.setHeader() 
const http = require('http');
const server = http.createServer((req, res) => {
    res.setHeader('Content-Type', 'text/html'); // 使用 setHeader() 设置 Content-Type
    res.writeHead(200, { // 又使用 writeHead() 设置 Content-Type
        'Content-Type': 'text/plain'
    });
    res.end('ok');
});
server.listen(8080, _ => {
    console.log('服务器开启成功,请访问:http://localhost:8080');
});
// 最终 content-type = text/plain
 
如果设置的标头字段包含无效字符,将抛出 TypeError
- 如果消息头尚未被发送,使用 
response.writeHead()的话,会先发送消息头;
可以通过response.statusCode和response.statusMessage编辑请求中的状态码statusCode和消息statusMessage 
response.statusCode = 500; // Internal Server Error	
response.statusMessage = '服务器内部错误,无法完成请求';
 
获取 get 请求的数据
req.url:获取 URL 路径,默认是/req.method:获取请求方式 -GET/POST
<body>
    <button id="box">点击触发</button>
</body>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
    box.onclick = () => {
        axios({
            method: "GET",
            url: "http://localhost:3030",
            params: { // 通过 params 设置 GET 传递的数据
                name: "superman"
            }
        }).then(res => {
            console.log("res", res);
            // res {data: 'ok', status: 200, statusText: 'OK', headers: {…}, config: {…}, …}
        })
    }
</script>
 
const http = require("http");
const url = require("url");
const server = http.createServer((req, res) => {
    // 解决跨域问题
    res.setHeader("Access-Control-Allow-Origin", "*")
    // 使用 url 模块解析 URL 路径,获取 URL 参数
    let paramsObj = url.parse(req.url, true).query;
    console.log("paramsObj", paramsObj); // paramsObj { name: 'superman' }
    res.write('ok'); // 响应请求
    res.end();
})
server.listen("3030", () => console.log("http://127.0.0.1:3030"));
 
获取 post 请求的数据
<body>
    <button id="box">点击触发</button>
</body>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
    box.onclick = () => {
        axios({
            method: "POST",
            url: "http://localhost:3030",
            data: { // 通过 data 设置 POST 传递的数据
                name: "superman"
            }
        }).then(res => {
            console.log("res", res);
            // res {data: 'ok', status: 200, statusText: 'OK', headers: {…}, config: {…}, …}
        })
    }
</script>
 
const http = require("http");
const server = http.createServer((req, res) => {
    // 解决跨域问题
    res.setHeader("Access-Control-Allow-Origin", "*")
    // 设置接受的自定义请求头
    res.setHeader("Access-Control-Allow-Headers", '*')
    // 监听 data 事件,获取 POST 传递的数据
    req.on("data", data => {
        console.log(data.toString()); // {"name":"superman"}
    });
    req.on("end", () => {}); // 关闭监听
    res.write('ok'); // 响应请求
    res.end();
})
server.listen("3030", () => console.log("http://127.0.0.1:3030"));
 
路由的使用
<body>
    <button id="box1">点击 get 请求 1</button>
    <button id="box2">点击 get 请求 2</button>
</body>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
    box1.onclick = () => {
        axios({
            url: "http://localhost:3030",
            method: "GET",
        }).then(res1 => {
            console.log('res1', res1);
            // res1 {data: '/ 路由', status: 200, statusText: 'OK', headers: {…}, config: {…}, …}
        })
    }
    box2.onclick = () => {
        axios({
            url: "http://localhost:3030/test",
            method: "GET",
        }).then(res2 => {
            console.log("res2", res2);
            // res2 {data: '/test 路由', status: 200, statusText: 'OK', headers: {…}, config: {…}, …}
        })
    }
</script>
 
const http = require("http");
const server = http.createServer((req, res) => {
    res.setHeader("Access-Control-Allow-Origin", "*")
    // 根据 req.url 设置路由
    console.log("路由路径", req.url);
    // 路由路径 /
    // 路由路径 /test
    if (req.url == "/") {
        res.write("/ 路由")
    } else if (req.url == "/test") {
        res.write("/test 路由")
    }
    res.end();
})
server.listen(3030, () => console.log("http://localhost:3030"));
 
 
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>node.html</title>
    <link rel="stylesheet" href="./index.css">
</head>
<body>
    <img src="./pic.jpg">
    <div>
        我是 node 页面
    </div>
</body>
</html>
 
/* index.css */
div {
    background-color: skyblue;
}
 
const http = require("http");
const fs = require("fs")
const server = http.createServer((req, res) => {
    // 根据路由返回页面
    console.log("路由地址", req.url);
    if (req.url == "/") {
        fs.readFile(__dirname + "/index.html", (err, data) => {
            res.end(data);
        })
    } else if (req.url == "/index.css") {
        fs.readFile(__dirname + "/index.css", (err, data) => {
            res.end(data)
        })
    } else if (req.url == "/pic.jpg") {
        fs.readFile(__dirname + "/pic.jpg", (err, data) => {
            res.end(data)
        })
    }
})
server.listen(3030, _ => console.log("http://127.0.0.1:3030"))










