用Puppeteer优化项目本地开发流程:一键获取登录Token

最近公司有个项目是基于vue开发的,但部分老页面是前后端不分离的;比如登录页面。由于后端也没有相关登录接口,所以每次在本地启动服务后,需要到测试环境登陆;然后手动复制几个cookie粘贴到本地启动的页面中,整个过程比较繁;所以用node写个脚本去简化一下流程。

优化前的登录流程

  • 本地npm run serve启动服务

  • 登录测试环境https://test.xxxx.com/login

  • 打开调试,找到相关cookie,复制

  • 打开本地启动的页面并打开调试;粘贴复制的cookie,刷新页面

优化过程

安装Puppeteer和readline

Puppeteer:

Puppeteer 是一个由 Google 开发的 Node.js 库,用于控制 headless 浏览器(无图形用户界面的浏览器)。它提供了一套高级的 API,允许开发者通过程序方式操控浏览器的行为,包括导航、表单提交、截图、生成 PDF 等功能。Puppeteer通常用于执行自动化测试、屏幕截图、搜索引擎爬虫等任务。在本例中,我们使用 Puppeteer 模拟用户登录过程,获取登录后的 Cookies。

readline:

readline 是 Node.js 内置的模块之一,提供了一个接口来从可读流(如 process.stdin)读取数据。它通常用于从终端接收用户输入,使得我们可以以交互的方式与用户进行通信。在本例中,我们使用 readline 创建了一个接口,以便用户能够在终端中输入账号和密码。

这两个模块的结合使用使得我们可以通过 Puppeteer 控制浏览器完成登录,而 readline 则使得用户能够在终端中直接输入账号和密码。

安装并引入模块

shell 复制代码
npm i puppeteer@20.0.0
npm i readline

引入 puppeteerreadlinefs

javascript 复制代码
const puppeteer = require('puppeteer')
const readline = require('readline')
const fs = require('fs')

定义登录函数

我们定义一个名为 login 的异步函数,用于模拟用户登录和获取 cookies。

javascript 复制代码
/**
* 登录
* @param {string} url 登录页面url
* @param {string} usernameSelector 登录页面用户名输入框的ID
* @param {string} passwordSelector 登录页面密码输入框的ID
* @param {string} username 账号
* @param {string} password 密码
*/
async function login(url, usernameSelector, passwordSelector, username, password) {
// ...

}

启动浏览器

login 函数中,使用 puppeteer.launch() 启动一个 headless 浏览器实例,然后通过page.goto打开我们传入的url。

javascript 复制代码
const browser = await puppeteer.launch({ headless: true })
const page = await browser.newPage()
await page.goto(url, { waitUntil: 'load' })

输入用户名和密码

使用 page.type() 模拟输入用户名和密码,其中第一个参数为输入框的选择器。登录完成后,我们再通过page.click去点击登录按钮。

javascript 复制代码
await page.type(usernameSelector, username)
await page.type(passwordSelector, password)
  
await page.click('#_btnLogin')
await page.waitForNavigation({ waitUntil: 'load' })

获取 Cookies

使用 page.cookies() 获取页面的 cookies,并将我们需要的token提取出来。我们这里就随便以APITOKENbpmftoken 为例子;提取后我们就可以使用browser.close()关闭浏览器。

javascript 复制代码
const cookies = await page.cookies()
const tokens = {}
for (const cookie of cookies) {
    cookie.name === 'APITOKEN' && (tokens.APITOKEN = cookie.value)
    cookie.name === 'bpmftoken' && (tokens.bpmftoken = cookie.value)
}
browser.close()

写入Tokens到文件

将获取到的tokens写入JSON文件并关闭终端。

javascript 复制代码
const tokenJSON = JSON.stringify(tokens, null, 2)
const filePath = './src/config/tokens.json'
fs.writeFile(filePath, tokenJSON, (err) => {
    if (err) throw err
    console.log('token已写入,请执行 npm run serve')
    process.exit(1)
});

访问终端输入数据

使用 readline 模块创建一个接口,获取用户输入的账号和密码。

javascript 复制代码
const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
})

let username = null;
let password = null;
const url = 'https://xxxx..com/login'; //登录页面
const usernameSelector = '#_txtUid'; //用户名输入框ID
const passwordSelector = '#_txtPwd'; //密码输入框ID

rl.question('请输入账号:', (answer) => {
    username = answer
    rl.question('请输入密码:', (answer) => {
        password = answer
        rl.close()
        login(url, usernameSelector, passwordSelector, username, password)
    })
});

终端执行下面命令即可实现获取token。

shell 复制代码
node login.js

然后在项目中通过读取/src/config/tokens.json中的内容去手动写入token即可。

完整代码如下:

javascript 复制代码
const puppeteer = require('puppeteer')
const readline = require('readline')
const fs = require('fs')

async function login(url, usernameSelector, passwordSelector, username, password) {
    const browser = await puppeteer.launch({ headless: true })
    const page = await browser.newPage()
    try {
        await page.goto(url, { waitUntil: 'load' })
        try {
            await page.type(usernameSelector, username)
            await page.type(passwordSelector, password)

        } catch (error) {
            console.log(error)
        }

        await page.click('#_btnLogin')
        await page.waitForNavigation({ waitUntil: 'load' })
        console.log('登录成功')
        await page.waitForTimeout(500)

        const cookies = await page.cookies()
        const tokens = {}
        for (const cookie of cookies) {
            cookie.name === 'APITOKEN' && (tokens.APITOKEN = cookie.value)
            cookie.name === 'bpmftoken' && (tokens.bpmftoken = cookie.value)
        }

        await browser.close()


        const tokenJSON = JSON.stringify(tokens, null, 2)

        const filePath = './src/config/tokens.json'

        fs.writeFile(filePath, tokenJSON, (err) => {
            if (err) throw err;
            console.log('token已写入, 请执行npm run serve')
            process.exit(1)
        })
    } catch (error) {
        console.error('Error:', error)
        await browser.close()
        process.exit(1)
    }
}


let username = null;
let password = null;
const url = 'https://xxxx..com/login'; //登录页面
const usernameSelector = '#_txtUid'; //用户名输入框ID
const passwordSelector = '#_txtPwd'; //密码输入框ID

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
})

rl.question('请输入账号(默认GP00164,直接回车): ', (answer) => {
    username = answer || 'GP00164';
    rl.question('请输入密码: (默认GP00164,直接回车)', (answer) => {
        password = answer || 'Xxzx2023@123'
        rl.close()
        login(url, usernameSelector, passwordSelector, username, password)
    })
})

总结

这样我们在本地开发过程中就不需要手动复制token,直接运行node login.js即可。当然Puppeteer可以做很多事情,比如自动化测试、屏幕截图和生成 PDF、爬虫、性能测试、表单自动填写等等,更多API可以查看官网学习。

欢迎关注我的掘金专栏:前端365,不定时分享前端知识。

往期推荐

相关推荐
崔庆才丨静觅3 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60614 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了4 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅4 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅5 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅5 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment5 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅5 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊5 小时前
jwt介绍
前端
爱敲代码的小鱼6 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax