微博、腾讯视频(部分)提取器-- 后台Node.js篇

提取器:主要功能是将输入的微博视频地址转换成可下载的视频地址

点击下载后台代码

app.js全部代码

const express = require("express");
const http = require("http")
const https = require("https");
const path = require("path");
var iconv = require("iconv-lite");
const app = express();

//设置静态资源根目录
app.use(express.static(path.join(__dirname, "public")));

// 拦截到所有的请求
app.all("*", function (req, res, next) {
    //设置允许跨域的域名,*代表允许任意域名跨域
    res.header("Access-Control-Allow-Origin", "*");
    //允许的header类型
    res.header("Access-Control-Allow-Headers", "content-type");
    //跨域允许的请求方式 
    res.header("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS");
    if (req.method.toLowerCase() == "options")
        res.send(200);  //让options尝试请求快速结束
    else
        next();
})

// 作为服务器接受来自浏览器的get请求
app.get("/getVideo", (req, res) => {

    // 微博视频来源
    if (!!req.query.videourl && req.query.videourl.startsWith('http://t.cn/')) {
        http.get(req.query.videourl, firstResponse => {
            const { statusCode } = firstResponse;
            if (statusCode == 302) {
                const { location } = firstResponse.headers;
                // 作为客户端向【微博服务器】发送http请求,方式为get(第二次)
                https.get(location, secondResponse => {
                    const { statusCode } = secondResponse;
                    if (statusCode == 302) {
                        const { location } = secondResponse.headers;
                        const startIndex = location.indexOf('//') + 2;
                        const endIndex = location.indexOf('/', startIndex);
                        // 作为客户端向【微博服务器】发送http请求,方式为get(第三次)
                        const httpreq = https.get({
                            host: location.substring(startIndex, endIndex),
                            port: 443,
                            path: location.substr(endIndex),
                            headers: {
                                // "Cookie": "SINAGLOBAL=3449239060440.6143.1571564937170; wvr=6; SUB=_2AkMpZuetf8NxqwJRmfgXxW_iZYh_yQDEieKfOhZ2JRMxHRl-yT9kqmoPtRB6AubJQgewqj9OLHJL43IGKJgFf_2WxcuS; SUBP=0033WrSXqPxfM72-Ws9jqgMF55529P9D9WFH5qiDNhwszhEYmWXn51ix; YF-V5-G0=f0aacce81fff76e1515ae68ac76a20c3; _s_tentry=passport.weibo.com; Apache=9408231403115.021.1580886172357; ULV=1580886172407:1:1:1:9408231403115.021.1580886172357:; WBStorage=42212210b087ca50|undefined; YF-Page-G0=d30fd7265234f674761ebc75febc3a9f|1580886234|1580886169"
                            }
                        }, response => {
                            response.on('data', (chunk) => {
                                // 检查微博服务器返回的字符串是否有包含视频的相关标记
                                if (chunk.toString().includes('video-sources')) {
                                    chunk = chunk.toString();
                                    const startIndex = chunk.indexOf('fluency=') + 8;
                                    const endIndex = chunk.indexOf(' ', startIndex) - 1;
                                    chunk = chunk.substring(startIndex, endIndex);
                                    chunk = unescape(chunk)
                                    res.send(chunk)
                                    return;
                                }
                            });
                        })
                        httpreq.on('error', (e) => {
                            console.error(`Got error: ${e.message}`);
                        });
                    }
                })
            }
        })
    }


})

// 根据不同的二级域名分别指向不同的静态目录
app.get('/', (req, res) => {
    // 获取URL中的主机信息
    let hostname = req.headers.host;
    hostname = hostname.substr(0, hostname.indexOf('.'));
    res.sendFile(path.join(__dirname, 'public', hostname, 'index.html'));
})
const ip = "127.0.0.1";
app.listen(80, ip, err => {
    if (err) throw err;
    console.log("启动成功!端口为80,IP地址:" + ip);
})

主要代码解读

代码行76--81

这段代码可以检测地址栏中的二级域名,然后根据不同的二级域名请求,将对应的后台目录中的index.html文件响应给前端。比喻,我们在前端请求test.mydomail.com时,后台可以拿到test标识,然后将后台工程目录中的test目录下的index.html返回给前端,这相当于test目录就是前端的主目录。这样,可以用不同的二级域名标识不同的前端工程项目。

代码行9

这段代码很重要, 因为前端拿到index.html文件后必然要在浏览器中加载进来, 这个加载的过程其实就是解析HTM标签的过程, 当浏览器遇到形如
<link href=video_extractor/assets/css/app.029c5e71.css rel=stylesheet>
<script src=video_extractor/assets/js/chunk-vendors.f918d654.js> </script>
等标签时必定再次向后台发送http请求, Node.js默认情况下不会处理类似的静态文件请求,除非声明如行9的代码.
至此,前端的第一次请求宣告完成,同时也意味着首页完成加载,等待用户的输入或点击

代码行26

app.get("/getVideo", (req, res) => {}) 表示其作为后台服务器端接受来自/getVideo路由(路径)的请求,req表示请求对象, res表示响应对象。
其中req有几个属性很重要,如query表示URL中?号后面的部分;

代码行30、35、42

http(s).get(url, req=>{})表示其作为客户端(也就是http请求端,典型如浏览器)向其他的后台服务器发送http请求,就好比某个后台服务并没有前端所请求的数据,但它可以向其他的后台请求数据,功能类似于代理、中介等,然后再返回给前端。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值