Liu Yu
发布于 2024-07-15 / 30 阅读
0
0

网页全景录制及 Puppeteer 功能设计及实现

前言

在生活中,无论是手机应用还是网页应用,经常会看到“意见反馈”功能,通过这个功能,用户可以将对产品的看法和期望提交给开发团队或运营团队,以 CNCF Sandbox 项目 Serverless Devs 官网为例,官网下方有快速反馈功能,为了配合该功能只需通过 Serverless 架构创建一个函数,在函数中进行相对应内容的记录与反馈即可,整个过程非常轻量与方便。本文将会通过 Serverless 架构与 HTML网页和快应用结合一同实现一款简单的意见反馈小软件。

技术架构

项目将会分为三个部分:

  • 服务端:构建在 Serverless 架构,主要是在函数计算服务中创建对应处理业务逻辑的函数;
  • HTML 端:通过 HTTP 触发器,触发函数计算,以实现用户反馈信息的记录或其他处理操作;
  • 快应用端:与 HTML 端行为一致,只不过是运行在快应用引擎中;

项目整体的技术架构如图1所示:

image.png

图1 简易用户反馈功能架构图

技术实现

服务端实现

为了简化服务端的内容,让功能更轻量化,此处将用户和反馈的内容进行整理,转发到运营人的邮箱中,整体的业务逻辑如下所示:

# -*- coding: utf8 -*-
import smtplib
from email.mime.text import MIMEText
from email.header import Header
import logging

def sendEmail(content):
    sender = 'service@52exe.cn'
    mail_msg = content
    message = MIMEText(mail_msg, 'html', 'utf-8')
    message['From'] = Header("用户反馈", 'utf-8')
    message['To'] = Header("用户", 'utf-8')
    subject = "用户反馈"
    message['Subject'] = Header(subject, 'utf-8')
    smtpObj = smtplib.SMTP_SSL("smtp.exmail.qq.com", 465)
    smtpObj.login(sender, '发件人邮箱密码')
    smtpObj.sendmail(sender, ['收件人邮箱地址'], message.as_string())

def handler(environ, start_response):
    context = environ['fc.context']
    request_uri = environ['fc.request_uri']
    # get request_body
    try:
        request_body_size = int(environ.get('CONTENT_LENGTH', 0))
    except (ValueError):
        request_body_size = 0
    request_body = environ['wsgi.input'].read(request_body_size)
    sendEmail(request_body)
    for k, v in environ.items():
      if k.startswith('HTTP_'):
        # process custom request headers
        pass
    status = '200 OK'
    response_headers = [('Content-type', 'text/plain')]
    start_response(status, response_headers)
    return ['我们已经收到了您的信息,会尽快给您回信'.encode("utf-8")]

网页端实现

网页端主要是通过 HTML 进行页面布局,通过网络请求模块进行数据提交。其中 Javascript 实现的部分代码如下所示:

function send() {
  const xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
  xmlhttp.onreadystatechange = function () {
    if (xmlhttp.readyState === 4 && xmlhttp.status === 200) {
      alert("我们已经收到了您的信息,会尽快给您回信")
    }
  }
  xmlhttp.open("POST", "请求地址");
  xmlhttp.setRequestHeader("Content-Type", "text/plain");
  xmlhttp.send(JSON.stringify({
    "name": document.getElementById("name").value,
    "email": document.getElementById("email").value,
    "content": document.getElementById("content").value,
  }));
}

快应用实现

在快应用中创建一个新的项目,主要涉及三个部分内容:

  • Template 部分:主要是页面布局,这里主要包括三部分,分别是Email的输入框、反馈信息的输入框以及确定按钮,参考代码如下:

    <template>
      <div class="tutorial-page">
        <div class="item">
          <div class="input-item">
            <text class="input-hint">您的邮箱:</text>
            <input class="input-text" name="email" type="text" @change= "bindEmailChange"></input>
          </div>
        </div>
    
        <div class="item">
          <div class="item-content">
            <text class="input-hint">反馈内容:</text>
            <textarea id="textarea" placeholder="请输入文本内容" class="textarea" @change="bindCententChange"></textarea>
          </div>
        </div>
    
        <div class="item">
          <div class="item-content">
            <input class="input-button" type="button" value="提交信息" onclick= "postData"></input>
          </div>
        </div>
      </div>
    </template>
    
  • Style 部分:主要是样式内容,类似于 HTML 项目中的 CSS 内容,参考代码如下:

    <style>
      .title {
        font-size: 40px;
        text-align: center;
      }
      .textarea {
        border: 1px solid #000000;
        width: 500px;
        height: 800px;
      }
      .input-text {
        border: 1px solid #000000;
        width: 500px;
      }
      .tutorial-page {
        /* 交叉轴居中 */
        align-items: center;
        /* 纵向排列 */
        flex-direction: column;
      }
      .tutorial-page > .item {
        /* 有剩余空间时,允许被拉伸 */
        /*flex-grow: 1;*/
        /* 空间不够用时,不允许被压缩 */
        flex-shrink: 0;
        /* 主轴居中 */
        justify-content: center;
        margin: 10px;
      }
    </style>
    
  • Script 部分:主要是行为与交互部分,例如通过点击按钮进行邮件发送等操作,参考代码如下:

    <script>
    import fetch from '@system.fetch'
    import prompt from '@system.prompt' 
    
    export default {
      data : {
          email: "",
          content: "",
      },
      bindEmailChange(e){
        console.log(e.value)
        this.$app.$data['email'] = e.value
      },
      bindCententChange(e){
        console.log(e.value)
        this.$app.$data['content'] = e.value
      },
      postData () {
        fetch.fetch({
          url: '后端服务地址',
          responseType: 'text',
          method: "POST",
          data: {
            content: this.$app.$data['content'],
            email: this.$app.$data['email'],
            name: 'QuickApp'
          },
          success: function (response) {
            prompt.showToast({
              message: `${response.data}`
            })
          },
          fail: function (data, code) {
            prompt.showToast({
              message: `提交失败`
            })
          }
        })
      }
    }
    </script>
    

完成上述代码的编写之后,如图2所示,在快应用的 IDE 中可以预览到整体效果,并进行代码的调试:

image-pwqq.png

图2 简易用户反馈功能快应用开发示意图

效果预览

如图3所示,CNCF Sandbox 项目 Serverless Devs 官网最下方有快速和我们反馈功能,该功能是基于上述内容实现:

image-nkgi.png

图3 Serverless Devs 官网快速反馈功能

通过快应用和上图所示的网页进行反馈,可以在邮箱中查看到对应的邮件内容,如图4所示:

image-ywsr.png

图4 简易反馈功能效果示意图

总结

至此为止,通过Serverless 架构实现的简单的用户反馈功能已经基本完成,通过本节,希望以抛砖引玉的方法,为读者提供一种新的灵感:Serverless 架构可以在很多轻量化的需求中发挥巨大的作用,凭借着其低运维、低成本特性,开发者只需要通过简单的几行代码,即可实现一套高可用的后端服务,通过 HTTP 触发器直接对外提供 RESTful API,无论从系统层还是从硬件层都无需付出更多精力,这种轻量的业务模型有助于业务的快速迭代与更新。


评论