ngrok本地调试原理及Telegram mini app cookie path 问题

ngrok本地调试原理及Telegram mini app cookie path 问题
Photo by Christian Wiediger / Unsplash

在现代web开发中,本地调试是一个非常重要的环节。然而,当我们需要将本地开发的应用暴露到公网以便进行测试时,就会遇到一些挑战。本文将详细介绍如何使用ngrok实现内网穿透进行本地调试,特别是在Telegram小程序开发场景中的应用,以及可能遇到的常见问题及其解决方案。

ngrok原理

ngrok是一个反向代理工具,它可以将本地服务器安全地暴露到公网。下面是ngrok的工作原理:

  1. 用户启动ngrok客户端,并指定要暴露的本地端口。
  2. ngrok客户端与ngrok云服务建立安全的通道。
  3. ngrok云服务生成一个公网可访问的URL。
  4. 当外部请求到达这个URL时,ngrok云服务将请求通过安全通道转发到本地ngrok客户端。
  5. 本地ngrok客户端将请求转发到指定的本地端口。
  6. 本地服务器处理请求并返回响应,响应通过相同的路径返回给客户端。

Telegram小程序调试场景

在Telegram小程序开发中,我们经常需要使用ngrok来进行本地调试。以下是具体步骤:

  1. 启动本地开发服务器(例如运行在localhost:3000)。
  2. 使用ngrok创建一个公网URL:Copyngrok http 3000
  3. ngrok会生成一个类似https://xxxx.ngrok.io的URL。
  4. 在Telegram BotFather中设置 bot domain, webapp direct url 为ngrok生成的domain。
  5. 现在,当用户与Telegram小程序交互时,请求会被转发到你的本地开发服务器。

常见问题及解决方案

Telegram小程序首次访问问题

问题描述: Telegram小程序首次访问会提示点击"visit"访问。如果首次访问的路径不是根路径"/",ngrok会将cookie设置到访问的路径下。这导致页面内的其他资源(通常在根路径"/")无法访问该cookie,从而可能引发资源文件被篡改为 点击"visit"访问。

解决方案:

  1. 确保首次访问路径为根路径"/"。
  2. 如果无法更改首次访问路径,可以在服务器端设置cookie时指定路径为"/":javascript res.cookie('sessionId', 'value', { path: '/' });
  3. 在前端,可以使用JavaScript来手动设置cookie:javascript document.cookie = "sessionId=value; path=/";

HTTPS证书问题

问题: ngrok生成的HTTPS URL可能会被浏览器标记为不安全。

解决方案:

  • 使用ngrok的付费版本,它提供了自定义域名和SSL证书的功能。
  • 在开发环境中,可以暂时忽略证书警告(不推荐在生产环境中这样做)。

连接不稳定

问题: 有时ngrok连接可能不稳定,导致服务中断。

解决方案:

  • 使用ngrok的配置文件来自动重连:
    yaml
    tunnels:
    myapp:
    proto:
    http
    addr: 3000
    auto_reconnect: true
  • 考虑使用其他类似工具,如localtunnel或frp。

Read more

Vue.js异步更新与nextTick机制深度解析(上篇)

Vue.js异步更新与nextTick机制深度解析(上篇)

本文目标 学完本文,你将能够: * 理解Vue.js为什么采用异步更新策略 * 掌握更新队列的设计思想和实现机制 * 深入理解Event Loop在Vue中的应用 * 了解nextTick的多种实现方式 系列导航 上一篇: Diff算法深度剖析 | 下一篇: Vue.js异步更新与nextTick机制(下篇) | 组件系统架构 引言:为什么DOM更新是异步的? 在Vue.js开发中,你可能遇到过这样的场景: // 场景1:连续修改数据 export default { data() { return { count: 0 } }, methods: { increment() { // 如果每次修改都立即更新DOM,会触发3次DOM更新 this.count++ // 触发一次? this.count++ // 触发一次? this.count++ // 触发一次? // 实际上:Vue只会触发一次DOM更新!

Vue.js组件系统架构深度解析

本文目标 学完本文,你将能够: * 理解Vue.js组件从创建到销毁的完整生命周期 * 掌握组件实例化和初始化的内部流程 * 深入理解父子组件通信的底层机制 * 学会实现完整的插槽系统(包括作用域插槽) * 掌握动态组件和异步组件的实现原理 * 应用组件级别的性能优化技巧 系列导航 上一篇: 异步更新与nextTick(下篇) | 下一篇: 状态管理模式 引言:组件是如何工作的? 在Vue.js开发中,我们每天都在使用组件。但你是否想过: // 当我们这样定义一个组件 const MyComponent = { data() { return { count: 0 } }, template: '<button @click="count++">{{ count }}</button>' } // 并使用它时 new Vue({ components: { MyComponent }, template:

Vue.js状态管理模式:构建可扩展的应用架构

本文目标 学完本文,你将能够: * 理解为什么大型应用需要状态管理 * 掌握Vuex的核心设计模式和实现原理 * 实现一个简化版的状态管理库 * 理解模块化和命名空间的设计思想 * 掌握大型应用的状态管理最佳实践 * 了解现代状态管理方案的演进 系列导航 上一篇: 组件系统架构 | 下一篇: 性能优化实践 1. 为什么需要状态管理? 1.1 组件通信的困境 在大型Vue.js应用中,组件间的通信会变得异常复杂: // 问题场景:多层级组件的状态共享 // GrandParent.vue <template> <Parent :user="user" @update-user="updateUser" /> </template> // Parent.vue <template> <Child

Vue.js依赖收集与追踪机制深度剖析

本文目标 学完本文,你将能够: * 理解Vue.js如何精确知道哪些组件需要更新 * 掌握Dep、Watcher、Observer三大核心类的协作机制 * 深入理解依赖收集的时机和完整过程 * 能够手写一个完整的依赖收集系统 * 解决实际开发中的依赖追踪问题 系列导航 上一篇: 响应式系统核心原理 | 下一篇: Virtual DOM实现详解 引言:为什么Vue知道哪些组件需要更新? 在使用Vue.js时,你是否想过这样一个问题:当我们修改一个数据时,Vue是如何精确地知道哪些组件用到了这个数据,并只更新这些组件的? // 假设有这样的场景 const app = new Vue({ data: { user: { name: 'John', age: 25 } } }); // 组件A只用到了user.name // 组件B只用到了user.age // 组件C同时用到了name和age // 当我们修改user.name时 app.user.name = 'Jane&