node.js实训

第一天:

  1. 音乐门户网站数据采集
    搜索列表数据采集
    歌曲MP3地址的获取

  2. node环境安装
    node环境的安装 — node安装包下载
    https://nodejs.org/en/

  3. visual studio code 编辑器的安装
    官网地址下载并直接安装即可
    https://code.visualstudio.com/

  4. node服务器搭建
    桌面上新建一个文件夹 node_server_demo
    终端 cd 到 新建的文件夹中
    通过 npm init 指令, 将 普通文件夹 node_server_demo,
    做成 项目文件夹, 此时 会在文件夹中生成一个
    package.json 文件
    将 改文件夹 拖拽到 vs code中, 打开, 开始写代码
    在文件夹 node_server_demo 中新建 index.js 文件
    在 index.js 文件中 , 开始写 服务器代码

  5. 题外话: cnpm 的安装
    题外话: npm 市场, 镜像 是国外, 所有有点慢
    我们需要另外一个指令: cnpm
    进行 是 过内容
    cnpm安装办法:

npm install -g cnpm --registry=https://registry.npm.taobao.org
  1. koa服务器模块安装及使用
    安装 服务器模块 koa
    cnpm install koa --save
    –save: 安装模块的同时, 是否将模块的依赖关系保存到
    package.json文件中
    用 koa 来搭建服务器
    在 node_modules 模块文件夹中, 找到 koa
    查看 koa 模块的 readme 文件, 里面有 代码说明
    代码 写完之后 , 运行项目:
    node index.js --------完事, 服务器成功了
    停止服务器的快捷键: ctr + C

尽量在服务器代码中, 增加一个打印, 告诉用户, 服务器跑起来了。。

代码示例

const Koa = require('koa');
const app = new Koa();
​
// response
app.use(ctx => {
  ctx.body = 'Hello Koa';
});
​
app.listen(3000);
  1. 让服务器具有 路由功能
    安装 koa-router 路由模块
cnpm install koa-router --save
 代码示例    不在 readme 中,  在 koa-router / lib / router.js 文件中 对
    抄过来的代码进行简单的修改 重要的:  	const Router = require('@koa/router'); 
    	需要修改成下面的引入方式 	const Router = require('koa-router'); 不同路由接口的示例代码:

const Koa = require('koa');
const app = new Koa();

​
// response
// 注释掉, 不要了
// app.use(ctx => {
//   ctx.body = 'Hello Koa';
// });
​
const Router = require('koa-router');
const router = new Router();
router.get('/abc', (ctx, next) => {
    ctx.body = "服务器 的abc界面"
}); 
​
app
    .use(router.routes())
    .use(router.allowedMethods());
​
app.listen(3000);
 

停止服务器 , 重新运行

  1. 让服务器具有 静态资源访问能力
    安装 koa-static 模块
cnpm install koa-static --save

readme 抄代码

const serve = require('koa-static');
// dirname: 整个项目的根路径
app.use(serve(dirname + '/static'));

停止服务器 , 重新运行

示例代码

const serve = require('koa-static');
// __dirname: 整个项目的根路径
app.use(serve(__dirname + '/static'));
  1. 让服务器 具有 文件上传能力
    安装 koa-body 模块
cnpm install koa-body --save

readme 抄代码

const koaBody = require('koa-body');
app.use(koaBody({
        multipart: true,
        formidable: {
                maxFieldsSize: 1024 * 1024 * 10
        }
}));

准备一个网页界面, 写出 文件上传的功能

 		未选择任何文件


服务器 提供 文件上传的接口 /upload

const fs = require("fs")

router.post('/upload', (ctx, next) => {
 		var xxx = ctx.request.files

    var file_path = xxx.sx.path
    var r = fs.createReadStream(file_path)
    var w = fs.createWriteStream("./static/diao.jpg")
    r.pipe(w)
​
    ctx.body = "9999999"
});

服务器 完成接收到的上传的文件, 并执行 保存功能

停止服务器 , 重新运行

完整示例代码

const koaBody = require('koa-body');
app.use(koaBody({
    multipart: true,
    formidable: {
        maxFieldsSize: 1024 * 1024 * 10
    }
}));


​
router.post('/upload', (ctx, next) => {
    var xxx = ctx.request.files
​
    var file_path = xxx.sx.path
    var r = fs.createReadStream(file_path)
    var w = fs.createWriteStream("./static/1111.jpg")
    r.pipe(w)
​
    ctx.body = "9999999"
});
 

 
  1. 前端 实现 ajax 网络请求, 请求服务器的某一个接口
var req = new XMLHttpRequest()
        req.open("GET" , "http://localhost:3000/xiaomi" , true)
        req.send()
        req.onreadystatechange = function () {
            if (req.readyState == 4 && req.status == 200) {
                console.log(req.responseText)
            }
        }
}
  1. 在服务器中完成 网络请求
    安装 网络请求模块 request
cnpm install request --save

使用 request 模块 对, 酷我 进行网络请求

将 请求 得到的酷我的数据 放到 ctx.body=数据 进行返回

示例代码

// 根据关键字 搜索 音乐 --- 接口
router.get('/shuju', async (ctx, next) => {
    var key_word =  ctx.request.query.sx
    key_word = encodeURIComponent(key_word)
    var kuwu_url = "http://www.kuwo.cn/api/www/search/searchMusicBykeyWord?key=" + key_word + "&pn=1&rn=30&httpsStatus=1&reqId=b7648390-e052-11eb-849b-edb625ef25be"
    var tou = {
        "Cookie": "_ga=GA1.2.2054600232.1625791052; _gid=GA1.2.1090010168.1625791052; Hm_lvt_cdb524f42f0ce19b169a8071123a4797=1625791052,1625822255; Hm_lpvt_cdb524f42f0ce19b169a8071123a4797=1625822272; kw_token=7O0VWI6F9WT",
        "csrf": "7O0VWI6F9WT",
        "Host": "www.kuwo.cn",
        "Referer": "http://www.kuwo.cn/search/list?key=%E5%91%A8%E6%9D%B0%E4%BC%A6",
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36"
    }
    
    
    var a = new Promise(function (aaa , bbb) {
        request.get({
            url: kuwu_url,
            headers: tou
        } , function (err , res , body) {
            if (err) {
                bbb(err)
            } else {
                aaa(body)
            }
        })
    })
    
    // var res = 酷我的 接口 返回的 数据
    ctx.body = await a
});

第二天

  1. 前后端交互, 获取音乐列表
    根据搜索音乐列表的接口, 通过代理服务器,实现音乐搜索功能的数据采集

前端ajax示例代码:

function search_fn() {
    var req = new XMLHttpRequest()
    req.open("GET" , "http://localhost:3000/shuju?sx=" + key_input.value , true)
    req.send()
    req.onreadystatechange = function () {
        if (req.readyState == 4 && req.status == 200) {
            music_list = JSON.parse(req.responseText)
            music_list = music_list.data.list
            console.log(music_list)
​
            var big_str = ""
            for (var i = 0; i < music_list.length; i++) {
                var a = music_list[i].name
                var b = music_list[i].artist
                var img_url = music_list[i].pic120
​
                big_str = big_str + '<li><img src="' + img_url + '" />' + a + '  ' + b + ' <button onclick="play_fn(' + i + ')">播放</button></li>'
​
            }
​
            music_wrap.innerHTML = big_str
        }
    }
}
 
  1. 列表歌曲播放功能
    得到音乐列表数据之后, 将数据放到 li 中进行界面展示, 当点解界面上播放按钮时,
    将当前所点击的播放按钮的音乐id后得到, 并传递给后台服务器,

播放按钮的示例代码:

<button onclick="play_fn(' + i + ')">播放</button>
function play_fn(music_index){
        play_index = music_index
        play_by_index(music_index)
 }
​
​
// 根据 播放坐标 实现具体歌曲的 播放功能
function play_by_index(music_index) {
    cur_play_data = music_list[music_index]
    var req = new XMLHttpRequest()
    req.open("GET" , "http://localhost:3000/get_mp3_by_id?rid=" + cur_play_data.rid , true)
    req.send()
    req.onreadystatechange = function () {
        if (req.readyState == 4 && req.status == 200) {
            var music_data = JSON.parse(req.responseText)
            var music_url = music_data.url
            my_audio.src = music_url
            my_audio.play()
        }
    }
​
}
 

让后台服务器 通过 该 id 号来获取该 歌曲的 mp3 播放地址
并返回给 前端网页

服务器获取 mp3 播放地址并返回的示例代码:

router.get("/get_mp3_by_id" , async (ctx , next) => {
    var rid = ctx.request.query.rid
    var format_mp3_url = "http://www.kuwo.cn/url?format=mp3&rid=" + rid + "&response=url&type=convert_url3&br=128kmp3&from=web&t=1625884737728&httpsStatus=1&reqId=f9e28c01-e127-11eb-bc58-479da32112ce"
    
    var a = new Promise(function (aaa , bbb) {
        request.get(format_mp3_url , function (err , res , body) {
            if (err) {
                bbb(err)
            } else {
                aaa(body)
            }
        })
    })
    
    ctx.body = await a
})
 

前端网页通过从后台得到的 mp3 播放地址, 进行歌曲的播放:
if (req.readyState == 4 && req.status == 200) {
    var music_data = JSON.parse(req.responseText)
    var music_url = music_data.url
    my_audio.src = music_url
    my_audio.play()
}
 

第三天

  1. 播放暂停功能
    通过对按钮描述信息的判断, 实现不同的功能 播放 / 暂停

示例代码:

// 播放 / 暂停的方法
play_or_pause.onclick = function () {
    // 获取元素身上的属性
    if (this.getAttribute("zhuangtai") == "playing") {
        my_audio.pause()
        this.innerHTML = "播放"
        this.setAttribute("zhuangtai" , "pausing")
        play_img.className = "play_img"
    } else {
        my_audio.play()
        this.innerHTML = "暂停"
        this.setAttribute("zhuangtai" , "playing")
        play_img.className = "play_img zhuan"
    }
​
}
  1. 上一曲 / 下一曲功能
    通过改变当前所播放的音乐下标来完成上一曲 或 下一曲功能

  2. 随机播放
    通过随机函数, 生成随机下标, 并完成随机播放功能

// 随机函数
function my_random(min , max) {
    return parseInt(Math.random()  * (max - min) + min)
}
  1. 单曲循环 / 列表循环
    枚举不同的 歌曲的播放模式, 根据不同的枚举值进行不同的处理操作
// 0:顺序播放  1:随机播放 2:单曲循环
var order_type = 0
​
​
// 切换播放顺序 按钮 的 点击事件
order_btn.onclick = function () {
    // 顺序播放
    // 随机播放
    // 单曲循环
    order_type++
    order_type = order_type % 3
    if (order_type == 0) {
        this.innerHTML = "顺序播放"
    } else if (order_type == 1) {
        this.innerHTML = "随机播放"
    } else if (order_type == 2) {
        this.innerHTML = "单曲循环"
    }
}
  1. 上一曲 、 下一曲 、 单曲循环 、 列表循环 、 随机播放 示例代码
// 上一曲 按钮 的 点击事件
prev_btn.onclick = function () {
    if (order_type == 0) {
        if (play_index == 0) {
​
        } else {
            play_index = play_index - 1
            play_by_index(play_index)
        }
​
    } else if (order_type == 1){
        play_index = 随机数
        play_by_index(随机数)
    } else if (order_type == 2) {
        play_by_index(play_index)
    }
​
}
​


// 下一曲 按钮 的 点击事件

next_btn.onclick = function () {
    if (order_type == 0) {
        play_index = play_index + 1
        play_index = play_index % music_list.length
        play_by_index(play_index)
​
    } else if (order_type == 1){
        var suiji_num = my_random(0 , music_list.length)
        play_index = suiji_num
        play_by_index(suiji_num)
    } else if (order_type == 2) {
        play_by_index(play_index)
    }
​
​
}
  1. 监听播放进度, 并通过时间和进度条来展示
    在界面上准备进度条, 并做好css样式
<div class="progress"></div>
/* 进度条 */
.progress{
    width: 90%;
    height: 20px;
    background: linear-gradient(to right , red 70% , blue 0%);
    margin: 0 auto;
}
准备好监听函数, 监听当前播放器的状态

// 播放器监听函数
function listen_audio() {
    var cur_time = my_audio.currentTime
    var all_time = my_audio.duration
    if (cur_time && all_time) {
        var percent = cur_time / all_time * 100
        // 将监听到的播放的百分比 绘制到 进度条上
        progress.style.background = "linear-gradient(to right , red " + percent + "% , blue 0%)"
​
        // 将监听到的时间, 同时时间函数的转换之后, 再绘制到界面上
        cur_time_wrap.innerHTML = format_time(cur_time)
        all_time_wrap.innerHTML = format_time(all_time)
    }
​
    requestAnimationFrame(listen_audio)
}
listen_audio()
​
​
// 时间格式的转换函数
function format_time(pass_time){
    // 123
    // 02:03
​
    var fen = parseInt(pass_time / 60)
    if (fen < 10) {
        fen = "0" + fen
    }
​
    var miao = parseInt(pass_time % 60)
    if (miao < 10) {
        miao = "0" + miao
    }
​
    return fen + ":" + miao
}
  1. 实现快进 、 快退功能
    给进度条增加点击事件函数, 并实现歌曲的 点击快进 、 快退的播放功能

示例代码:

// 进度条的点击事件
progress.onclick = function () {
    var percent = event.offsetX / this.offsetWidth
    my_audio.currentTime = my_audio.duration * percent
}

第四天

  1. CSS布局 ---- 定位布局
    定位:position
    四种定位方式:
    1. static 静态定位 没有开定位
    2. fixed 固定定位 开定位了 固定到窗口上
    参照物: 窗口
    3. relative: 相对定位 开定位了 相对自己原有的位置进行定位
    参照物: 自己 原有的位置
    4. absolute: 绝对定位 开定位了 在某一定的定位范围之内进行定位
    参照物: 已开定位的范围

    元素必须开定位:
    上下左右(top , bottom , left , right) 才管用

    使用技巧
    父元素 开 定位 relative
    给子元素 开 absolute

    left > right
    top > bottom

    通过定位让元素居中的问题:
  2. 让元素懵
  3. 给元素开 margin:auto;
  4. CSS布局 ---- 浮动布局
    浮动 ----- 飘:
    1.float: 只有 两个方向 left 和 right
    2. 浮动的元素 必然 会 影响自己的兄弟(兄弟可以和净化: clear:both;)
    3. 一个元素 要想浮动, 先看自己的哥哥
    如果 自己的哥哥浮动了, 那么跟着自己的哥哥浮动
    如果 自己的哥哥没有浮动, 那么在自己哥哥的下一行进行浮动

    浮动的元素 永远不能超出父视图的 横向范围
  5. CSS布局 ---- 弹性布局
    弹性布局:
    1. 给父元素 开启 弹性盒子模式
    2. 子元素 按照弹性比例值, 进行区域划分就可以
    3. 弹性布局的方式, 默认是横向布局方式
    4. 比例值的运算规则: 按照父元素的剩余空间, 进行比例的划分
    5. 有两个用来控制 布局位置的 单词
      justify-content: 主轴
      align-item: 次轴
      弹性布局的方向 ==== 主轴
      另外一个方向 ==== 次轴
  6. CSS ---- 弹性正方形
.test{
    width: 10%;
    height: 0px;
    border: 1px solid black;
    padding-top: 10%;
    background-color: lightblue;
}
  1. CSS ---- 三角形
.test{
    width: 0px;
    height: 0px;
    /* border: 60px solid black; */
    /* background-color: lightblue; */
​
    border-left: 60px solid yellow;
    border-right: 60px solid transparent;
    border-top: 60px solid yellow;
    border-bottom: 60px solid yellow;
    border-radius: 50%;
}
  1. 上午完善该项目, 下午项目答辩
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值