最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Express代理轉發(fā)服務器實現

 更新時間:2023年05月11日 11:22:31   作者:the_way_inf  
這篇文章主要為大家介紹了Express代理轉發(fā)服務器實現技巧詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

express的代理轉發(fā)

其實我的內心關于這個Express,我的內心是拒絕的,不是說,我對這個框架有什么看法,而是因為這個大作業(yè)的問題。是的我還是一個大三老菜雞,苦練 Java 全干開發(fā),Python 人工智能 整整 一坤年。期間拿了幾個獎,水了篇論文 而已。

那么這篇文章主要做的,其實很簡單就是,做個代理轉發(fā)。前端請求,先到express服務器,然后轉發(fā)到flask服務器,為什么非要轉發(fā)呢,原因很簡單,web作業(yè)非要用node平臺,沒辦法,但是我的服務已經用flask做好了,當然這個和我先前寫的那個微信聊天的不一樣哈,這個是另一個,是視覺識別算法,說到這個,我本人目前也在手寫一個全新的目標檢測算法,希望可以起到不錯的效果,扯遠了。所以沒有辦法,只能做一個express的代理轉發(fā)。

但是呢,為了體現工作量,我在這個轉發(fā)服務器里面加了點東西:

就是這個,加點curd,不然不好混。

項目結構

這個的話,更像是一個dome,所以的話,項目結構非常簡單。

因為核心功能就一個,就是做轉發(fā),然后呢,加上一些配套的記錄就好了。

然后就是我們的數據庫還有頁面之類的。當然整個項目還是使用這個生成工具先生成了一個模板工程的。

由于整個項目簡單,骨架也是生成的,所以我這邊就只說,它的一些核心實現了。

轉發(fā)

那么首先就是我們的核心,代理轉發(fā):

const proxy = require("http-proxy-middleware").createProxyMiddleware;
app.use(
    "/",
    proxy(
        [`/api/**`], {
            target: `http://www.httpbin.org/anything/`,
            changeOrigin: true,
            onProxyReq: (proxyReq, req, res) => {
                // 在代理請求發(fā)送到目標服務器之前,對請求頭進行修改
                const sourceUrl = req.originalUrl;
                const targetUrl = "your address";
                db.insertProxy(sourceUrl, targetUrl, (err, id) => {
                    if (err) {
                        console.error(err);
                    } else {
                        console.log(`New proxy request saved with ID ${id}.`);
                    }
                });
            },
            onProxyRes: (proxyRes, req, res) => {
                // 在代理服務器收到目標服務器的響應后,對響應頭進行修改
                proxyRes.headers['x-custom-header'] = 'Huterox';
            }
        },
    ),
);

轉發(fā)記錄

然后其實就是我們的轉發(fā)記錄的了。這里的話我使用的是sqlite3。

這邊把一些方法都封裝到了db.js當中去了。

const sqlite3 = require('sqlite3').verbose();
// 創(chuàng)建數據庫連接
const db = new sqlite3.Database('./db.sqlite', err => {
    if (err) {
        console.error(err.message);
    } else {
        console.log('Connected to the db.sqlite database.');
    }
});
// 創(chuàng)建表
const createTable = () => {
    db.run(
        `CREATE TABLE IF NOT EXISTS proxies (
      id INTEGER PRIMARY KEY AUTOINCREMENT,
      source_url TEXT NOT NULL,
      target_url TEXT NOT NULL,
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    )`,
        err => {
            if (err) {
                console.error(err.message);
            } else {
                console.log('Table proxies created successfully.');
            }
        }
    );
};
//查找
const searchProxy = function(keyword, offset, limit, callback) {
    const pattern = `%${keyword}%`;
    const countSql = `SELECT COUNT(*) as count FROM proxies WHERE source_url LIKE ? OR target_url LIKE ?`;
    const sql = `SELECT * FROM proxies WHERE source_url LIKE ? OR target_url LIKE ? ORDER BY created_at DESC LIMIT ? OFFSET ?`;
    db.get(countSql, [pattern, pattern], (err, row) => {
        if (err) {
            callback(err, {});
            return;
        }
        const totalCount = row.count;
        db.all(sql, [pattern, pattern, limit, offset], (err, rows) => {
            if (err) {
                callback(err);
                return;
            }
            const proxies = rows.map(row => ({
                id: row.id,
                sourceUrl: row.source_url,
                targetUrl: row.target_url,
                createdAt: row.created_at,
            }));
            callback(null, { proxies, totalCount });
        });
    });
};
// 插入一條記錄
const insertProxy = (sourceUrl, targetUrl, callback) => {
    db.run(`INSERT INTO proxies (source_url, target_url) VALUES (?, ?)`, [sourceUrl, targetUrl], err => {
        if (err) {
            console.error(err.message);
            callback(err.message, null);
        } else {
            console.log('New proxy added successfully.');
            db.get(`SELECT last_insert_rowid() as id`, (err, row) => {
                callback(null, row.id);
            });
        }
    });
};
// 根據 ID 查詢代理轉發(fā)記錄
const getProxyById = (id, callback) => {
    db.get(`SELECT * FROM proxies WHERE id = ?`, [id], (err, row) => {
        if (err) {
            console.error(err.message);
            callback(err.message, null);
        } else {
            console.log(`Proxy with ID ${id} found.`);
            callback(null, row);
        }
    });
};
// 查詢所有代理轉發(fā)記錄
const getAllProxies = callback => {
    db.all(`SELECT * FROM proxies ORDER BY id`, (err, rows) => {
        if (err) {
            console.error(err.message);
            callback(err.message, null);
        } else {
            console.log('All proxies fetched successfully.');
            callback(null, rows);
        }
    });
};
// 更新代理轉發(fā)記錄
const updateProxyById = (id, sourceUrl, targetUrl, callback) => {
    db.run(
        `UPDATE proxies SET source_url = ?, target_url = ? WHERE id = ?`, [sourceUrl, targetUrl, id],
        err => {
            if (err) {
                console.error(err.message);
                callback(err.message, null);
            } else {
                console.log(`Proxy with ID ${id} updated successfully.`);
                callback(null, true);
            }
        }
    );
};
// 根據 ID 刪除代理轉發(fā)記錄
const deleteProxyById = (id, callback) => {
    db.run(`DELETE FROM proxies WHERE id = ?`, [id], err => {
        if (err) {
            console.error(err.message);
            callback(err.message, null);
        } else {
            console.log(`Proxy with ID ${id} deleted successfully.`);
            callback(null, true);
        }
    });
};
createTable();
module.exports = {
    insertProxy,
    getProxyById,
    getAllProxies,
    searchProxy,
    updateProxyById,
    deleteProxyById
};

當然只有這個還不夠,我們還有對應的curd的接口才行。

所以在app.js里面去注冊這些接口。

app.get('/logs/proxy', (req, res) => {
    const { keyword = '', offset = 0, limit = 10 } = req.query;
    db.searchProxy(keyword, Number(offset), Number(limit), (err, result) => {
        if (err) {
            console.error(err);
            res.status(500).send('Internal server error.');
        } else {
            res.json({
                rows: result.proxies,
                count: result.totalCount
            });
            console.log("當前記錄條數:" + result.totalCount)
        }
    });
});
app.post('/logs/proxy', (req, res) => {
    const { sourceUrl, targetUrl } = req.body;
    db.insertProxy(sourceUrl, targetUrl, (err, row) => {
        if (err) {
            console.error(err);
            res.status(500).send('Internal server error.');
        } else {
            res.json(row);
        }
    });
});
app.delete('/logs/proxy/:id', (req, res) => {
    const id = req.params.id;
    db.deleteProxy(id, (err) => {
        if (err) {
            console.error(err);
            res.status(500).send('Internal server error.');
        } else {
            res.status(204).end();
        }
    });
});

前端頁面

之后,就是我們的前端頁面,這個頁面的話,好辦,我們就直接使用html來寫了。 訪問/logs 就可以訪問頁面:

app.get('/logs', (req, res) => {
    res.sendFile(__dirname + '/public/logs.html');
});

對應的html代碼如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>代理日志查看</title>
    <link rel="stylesheet"  rel="external nofollow" >
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="https://unpkg.com/element-ui/lib/index.js"></script>
</head>
<style>
    /* 設置全局字體和顏色 */
    #app {
        margin: 0 auto;
        width: 80%;
    }
</style>
<body>
    <div id="app">
        <h1>代理日志</h1>
        <el-form inline>
            <el-form-item label="關鍵字">
                <el-input v-model="keyword" placeholder="輸入關鍵字進行搜索"></el-input>
            </el-form-item>
            <el-form-item>
                <el-button type="primary" icon="el-icon-search" v-on:click="search">搜索</el-button>
            </el-form-item>
        </el-form>
        <el-table :data="records" stripe>
            <el-table-column prop="id" label="ID" width="100"></el-table-column>
            <el-table-column prop="sourceUrl" label="請求路徑" width="300"></el-table-column>
            <el-table-column prop="targetUrl" label="目標地址" width="300"></el-table-column>
            <el-table-column prop="timestamp" label="時間" width="200">
                <template slot-scope="scope">{{ new Date(scope.row.createdAt).toLocaleString() }}</template>
            </el-table-column>
            <el-table-column label="操作" width="200">
                <template slot-scope="scope">
          <el-button type="danger" icon="el-icon-delete" v-on:click="removeRecord(scope.row.id)">刪除</el-button>
        </template>
            </el-table-column>
        </el-table>
        <el-pagination layout="total, prev, pager, next" :total="total" v-on:current-change="changePage"></el-pagination>
    </div>
    <script>
        const app = new Vue({
            el: '#app',
            data: {
                records: [],
                keyword: '',
                current: 1,
                pageSize: 10,
                total: 0
            },
            methods: {
                search: function() {
                    this.current = 1;
                    this.loadRecords();
                },
                removeRecord: function(id) {
                    this.$confirm('確定刪除該記錄?')
                        .then(() => {
                            axios.delete(`/logs/proxy/${id}`)
                                .then(() => {
                                    this.loadRecords();
                                    this.$message.success('刪除成功!');
                                })
                                .catch(() => {
                                    this.$message.error('刪除失??!');
                                });
                        })
                        .catch(() => {});
                },
                changePage: function(page) {
                    this.current = page;
                    this.loadRecords();
                },
                loadRecords: function() {
                    axios.get('/logs/proxy', {
                            params: {
                                keyword: this.keyword,
                                offset: (this.current - 1) * this.pageSize,
                                limit: this.pageSize
                            }
                        })
                        .then(res => {
                            this.records = res.data.rows;
                            this.total = res.data.count;
                        })
                        .catch(err => console.error(err));
                }
            },
            mounted: function() {
                this.loadRecords();
            }
        });
    </script>
</body>
</html>

那么之后的話,這個簡單的代理轉發(fā)服務器就寫好了。強行加上一層,服了。

以上就是Express代理轉發(fā)服務器實現的詳細內容,更多關于Express代理轉發(fā)服務器的資料請關注腳本之家其它相關文章!

相關文章

最新評論

东至县| 扶沟县| 武鸣县| 左云县| 营山县| 通江县| 和林格尔县| 桐乡市| 丹阳市| 白沙| 台州市| 连山| 来安县| 个旧市| 洛川县| 林口县| 新乡市| 利津县| 昭觉县| 临朐县| 呼玛县| 综艺| 手机| 根河市| 隆子县| 越西县| 永泰县| 墨竹工卡县| 永康市| 额济纳旗| 迭部县| 宜阳县| 塔河县| 和政县| 上高县| 潮州市| 巴马| 漳浦县| 察隅县| 北京市| 烟台市|