{"componentChunkName":"component---src-templates-blog-detail-tsx","path":"/blog/2020-04-23-serverless-scf-cos","result":{"data":{"currentBlog":{"id":"07918513-5a0f-5c41-b33c-209be7389654","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/202068/1591592273724-70zt6hhv58%20%281%29.png","authors":["乂乂又又"],"categories":["user-stories"],"date":"2020-04-23T00:00:00.000Z","title":"万物皆可 Serverless 之使用云函数 SCF+COS 快速开发全栈应用","description":"我是在一个前端初学者的背景下，前后仅花了大概三天的时间，就完成了一个比较简单的网页应用，这就是 Severless 的魅力所在，它可以让你快速开发上线全栈应用，无论你是前端或是后端开发者都可以获益许多。","authorslink":["https://cloud.tencent.com/developer/article/1612750"],"translators":null,"translatorslink":null,"tags":["全栈应用","云函数"],"keywords":"Serverless,Serverless全栈,Serverless应用","outdated":true},"wordCount":{"words":340,"sentences":82,"paragraphs":82},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-04-23-serverless-scf-cos.md","fields":{"slug":"/blog/2020-04-23-serverless-scf-cos/","keywords":["java","python","serverless","spa","腾讯云无服务器云函数","无服务器","无服务器云函数","云函数","函数","cos","json","serverlesscloud","event","blackMap"]},"html":"<p>我一直想做一个网页应用，奈何没有系统学习过前端，直到后来我接触到腾讯云无服务器云函数 SCF，让前端可以快速获得后端的能力同时，一并解决了前端数据请求跨域的问题。</p>\n<p>没错，云函数 SCF 就是那种一旦用了就无法回到原来那种神奇的东西，让人不禁感叹为什么没有早点遇到 SCF</p>\n<p>然后我花了大概一天的时间编写调试上线发布云函数（应用后端），然后又用了一天的时间学了下前端，主要是确定要用到的技术栈（后面我会再讲到这个问题），然后第三天正式开始开发应用，将云函数引入前端调用，测试数据，调整布局，打包网页发布到 coding pages。</p>\n<p><strong>所以在我是一个前端初学者的背景下，前后仅花了大概三天的时间，就完成了这样一个比较简单的网页应用</strong></p>\n<p>这就是 Severless 的魅力所在，它可以让你快速开发上线全栈应用，无论你是前端或是后端开发者都可以获益许多。</p>\n<h2 id=\"效果展示\"><a href=\"#%E6%95%88%E6%9E%9C%E5%B1%95%E7%A4%BA\" aria-label=\"效果展示 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>效果展示</h2>\n<ul>\n<li>首页</li>\n</ul>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590202785387-16206.jpg\" alt=\"首页\"></p>\n<ul>\n<li>视频播放页</li>\n</ul>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590202785551-16206.jpg\" alt=\"视频播放页\"></p>\n<p>更详细的体验可访问 <a href=\"https://wo-cao.cn/\">https://wo-cao.cn/</a> ，仅做测试之用，不要乱搞哦~</p>\n<p>是不是有点跃跃欲试涅？让我们开始吧~</p>\n<h2 id=\"前端部分\"><a href=\"#%E5%89%8D%E7%AB%AF%E9%83%A8%E5%88%86\" aria-label=\"前端部分 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>前端部分</h2>\n<p>由于初涉前端，前端丰富得让人眼花缭乱的生态让我花费了一整天的时间来确定所要用的框架。</p>\n<p>这里大体说下我用到的前端技术栈，帮助小伙伴快速进入实际开发状态，不要像我这个前端小白一样在框架的选择上耗费太多时间</p>\n<table>\n<thead>\n<tr>\n<th align=\"left\">需求</th>\n<th align=\"left\">第三方库</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"left\">html预编译</td>\n<td align=\"left\">Pug</td>\n</tr>\n<tr>\n<td align=\"left\">css预编译</td>\n<td align=\"left\">Stylus</td>\n</tr>\n<tr>\n<td align=\"left\">js预编译</td>\n<td align=\"left\">TypeScript、Bable</td>\n</tr>\n<tr>\n<td align=\"left\">开发框架</td>\n<td align=\"left\">Vue</td>\n</tr>\n<tr>\n<td align=\"left\">代码美化</td>\n<td align=\"left\">ESlint、Prettier</td>\n</tr>\n<tr>\n<td align=\"left\">网页打包</td>\n<td align=\"left\">Parcel</td>\n</tr>\n<tr>\n<td align=\"left\">状态管理</td>\n<td align=\"left\">Vuex</td>\n</tr>\n<tr>\n<td align=\"left\">UI组件</td>\n<td align=\"left\">Wired-Elements</td>\n</tr>\n<tr>\n<td align=\"left\">视频播放</td>\n<td align=\"left\">Dplayer、Hls.js</td>\n</tr>\n<tr>\n<td align=\"left\">数据请求</td>\n<td align=\"left\">Axios</td>\n</tr>\n</tbody>\n</table>\n<p>然后贴一下搜索列表页面的源码，展示一下 <strong>Vue+Pug+TypeScript+Stylus</strong> 写起网页来有多<del>酸爽</del></p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"83351252222085870000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`<template lang=&quot;pug&quot;>\n  div(style=&quot;margin:2.5vw;display: flex;flex-wrap: wrap;&quot;)\n    div#box(v-bind:class=&quot;pc ? 'box_pc' : 'box_phone'&quot; v-bind:value=&quot;item.title&quot; v-for=&quot;(item,index) in items&quot; @click=&quot;playx(index)&quot;)\n      wired-image(v-bind:class=&quot;pc ? 'img_pc' : 'img_phone'&quot; elevation=&quot;2&quot; :src=&quot;item.cover&quot;)\n      div(style='width:100%;')\n        p(style=&quot;text-align: center;font-size:1rem;&quot;) {{ item.title }}\n</template>\n\n<script lang=&quot;ts&quot;>\nimport 'wired-elements'\nimport { open, pc, refreshPath } from '../app/tools/window'\n\nexport default {\n  name: 'ResultList',\n  data() {\n    return {\n      pc: true,\n      items: this.\\$store.getters.getJsonState\n    }\n  },\n  mounted() {\n    this.pc = pc ? true : false\n  },\n  methods: {\n    playx(index: number) {\n      let video = this.items[index]\n      this.\\$store.commit('setPlayState', video)\n      open(this, video.title, '/play')\n    }\n  }\n}\n</script>\n\n<style lang=&quot;stylus&quot; scoped>\n.img_pc\n  max-width 17vw\n.img_phone\n  max-width 22vw\n.box_pc\n  margin:3vw;\n  flex: 0 0 13%;\n.box_phone\n  margin:2.5vw;\n  flex: 0 0 28%;\n</style>`, `83351252222085870000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token operator\">&lt;</span>template lang<span class=\"token operator\">=</span><span class=\"token string\">\"pug\"</span><span class=\"token operator\">></span>\n  <span class=\"token function\">div</span><span class=\"token punctuation\">(</span>style<span class=\"token operator\">=</span><span class=\"token string\">\"margin:2.5vw;display: flex;flex-wrap: wrap;\"</span><span class=\"token punctuation\">)</span>\n    div<span class=\"token function\">#box</span><span class=\"token punctuation\">(</span>v<span class=\"token operator\">-</span>bind<span class=\"token punctuation\">:</span><span class=\"token keyword\">class</span><span class=\"token operator\">=</span><span class=\"token string\">\"pc ? 'box_pc' : 'box_phone'\"</span> v<span class=\"token operator\">-</span>bind<span class=\"token punctuation\">:</span>value<span class=\"token operator\">=</span><span class=\"token string\">\"item.title\"</span> v<span class=\"token operator\">-</span><span class=\"token keyword\">for</span><span class=\"token operator\">=</span><span class=\"token string\">\"(item,index) in items\"</span> @click<span class=\"token operator\">=</span><span class=\"token string\">\"playx(index)\"</span><span class=\"token punctuation\">)</span>\n      wired<span class=\"token operator\">-</span><span class=\"token function\">image</span><span class=\"token punctuation\">(</span>v<span class=\"token operator\">-</span>bind<span class=\"token punctuation\">:</span><span class=\"token keyword\">class</span><span class=\"token operator\">=</span><span class=\"token string\">\"pc ? 'img_pc' : 'img_phone'\"</span> elevation<span class=\"token operator\">=</span><span class=\"token string\">\"2\"</span> <span class=\"token punctuation\">:</span>src<span class=\"token operator\">=</span><span class=\"token string\">\"item.cover\"</span><span class=\"token punctuation\">)</span>\n      <span class=\"token function\">div</span><span class=\"token punctuation\">(</span>style<span class=\"token operator\">=</span><span class=\"token string\">'width:100%;'</span><span class=\"token punctuation\">)</span>\n        <span class=\"token function\">p</span><span class=\"token punctuation\">(</span>style<span class=\"token operator\">=</span><span class=\"token string\">\"text-align: center;font-size:1rem;\"</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">{</span> item<span class=\"token punctuation\">.</span>title <span class=\"token punctuation\">}</span><span class=\"token punctuation\">}</span>\n<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>template<span class=\"token operator\">></span>\n\n<span class=\"token operator\">&lt;</span>script lang<span class=\"token operator\">=</span><span class=\"token string\">\"ts\"</span><span class=\"token operator\">></span>\n<span class=\"token keyword\">import</span> <span class=\"token string\">'wired-elements'</span>\n<span class=\"token keyword\">import</span> <span class=\"token punctuation\">{</span> open<span class=\"token punctuation\">,</span> pc<span class=\"token punctuation\">,</span> refreshPath <span class=\"token punctuation\">}</span> <span class=\"token keyword\">from</span> <span class=\"token string\">'../app/tools/window'</span>\n\n<span class=\"token keyword\">export</span> <span class=\"token keyword\">default</span> <span class=\"token punctuation\">{</span>\n  name<span class=\"token punctuation\">:</span> <span class=\"token string\">'ResultList'</span><span class=\"token punctuation\">,</span>\n  <span class=\"token function\">data</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span>\n      pc<span class=\"token punctuation\">:</span> <span class=\"token boolean\">true</span><span class=\"token punctuation\">,</span>\n      items<span class=\"token punctuation\">:</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>$store<span class=\"token punctuation\">.</span>getters<span class=\"token punctuation\">.</span>getJsonState\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  <span class=\"token function\">mounted</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>pc <span class=\"token operator\">=</span> pc <span class=\"token operator\">?</span> <span class=\"token boolean\">true</span> <span class=\"token punctuation\">:</span> <span class=\"token boolean\">false</span>\n  <span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n  methods<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token function\">playx</span><span class=\"token punctuation\">(</span><span class=\"token parameter\">index<span class=\"token punctuation\">:</span> number</span><span class=\"token punctuation\">)</span> <span class=\"token punctuation\">{</span>\n      <span class=\"token keyword\">let</span> video <span class=\"token operator\">=</span> <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>items<span class=\"token punctuation\">[</span>index<span class=\"token punctuation\">]</span>\n      <span class=\"token keyword\">this</span><span class=\"token punctuation\">.</span>$store<span class=\"token punctuation\">.</span><span class=\"token function\">commit</span><span class=\"token punctuation\">(</span><span class=\"token string\">'setPlayState'</span><span class=\"token punctuation\">,</span> video<span class=\"token punctuation\">)</span>\n      <span class=\"token function\">open</span><span class=\"token punctuation\">(</span><span class=\"token keyword\">this</span><span class=\"token punctuation\">,</span> video<span class=\"token punctuation\">.</span>title<span class=\"token punctuation\">,</span> <span class=\"token string\">'/play'</span><span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span>\n  <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span>\n<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>script<span class=\"token operator\">></span>\n\n<span class=\"token operator\">&lt;</span>style lang<span class=\"token operator\">=</span><span class=\"token string\">\"stylus\"</span> scoped<span class=\"token operator\">></span>\n<span class=\"token punctuation\">.</span>img_pc\n  max<span class=\"token operator\">-</span>width <span class=\"token number\">17</span>vw\n<span class=\"token punctuation\">.</span>img_phone\n  max<span class=\"token operator\">-</span>width <span class=\"token number\">22</span>vw\n<span class=\"token punctuation\">.</span>box_pc\n  margin<span class=\"token punctuation\">:</span><span class=\"token number\">3</span>vw<span class=\"token punctuation\">;</span>\n  flex<span class=\"token punctuation\">:</span> <span class=\"token number\">0</span> <span class=\"token number\">0</span> <span class=\"token number\">13</span><span class=\"token operator\">%</span><span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">.</span>box_phone\n  margin<span class=\"token punctuation\">:</span><span class=\"token number\">2.5</span>vw<span class=\"token punctuation\">;</span>\n  flex<span class=\"token punctuation\">:</span> <span class=\"token number\">0</span> <span class=\"token number\">0</span> <span class=\"token number\">28</span><span class=\"token operator\">%</span><span class=\"token punctuation\">;</span>\n<span class=\"token operator\">&lt;</span><span class=\"token operator\">/</span>style<span class=\"token operator\">></span></code></pre></div>\n<p>具体的开发过程就不细讲了，因为我本身只是前端初学者，继续讲下去难免有班门弄斧，误导他人的嫌疑~</p>\n<p>然后这篇文章主要是讲如何借助腾讯云 SCF+<a href=\"https://cloud.tencent.com/product/cos?from=10680\">COS</a>快速实现网页的后端能力，下面我们就直接进入后端部分了。</p>\n<h2 id=\"后端部分\"><a href=\"#%E5%90%8E%E7%AB%AF%E9%83%A8%E5%88%86\" aria-label=\"后端部分 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>后端部分</h2>\n<p>这一部分那我会分成两点展开，一个是腾讯云 Severless 开发环境的配置，另一个是本地云函数的开发调试和上线过程。</p>\n<p>下面就让我们一起来解开 Severless 的神秘面纱一探究竟吧~</p>\n<h3 id=\"1-安装-tencent-serverless-toolkit-for-vs-code\"><a href=\"#1-%E5%AE%89%E8%A3%85-tencent-serverless-toolkit-for-vs-code\" aria-label=\"1 安装 tencent serverless toolkit for vs code permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>1. 安装 Tencent Serverless Toolkit for VS Code</h3>\n<p>所谓工欲善其事，必先利其器。为了更快速的开发调试发布云函数，我们需要先安装腾讯云官方的 Tencent Serverless 插件</p>\n<p>相信我，你会爱死它的，它打通了云函数编写、调试和上线发布的所有流程，真正做到了一条龙服务</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590202785786-16206.jpg\" alt=\"云函数官方文档\"></p>\n<p>官方文档在这一块讲的还是蛮细致用心的，赞！感兴趣的同学可以去看下<a href=\"https://cloud.tencent.com/document/product/583/37511?from=10680\">《使用VS Code插件创建函数 》</a></p>\n<h3 id=\"2-编写云函数\"><a href=\"#2-%E7%BC%96%E5%86%99%E4%BA%91%E5%87%BD%E6%95%B0\" aria-label=\"2 编写云函数 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>2. 编写云函数</h3>\n<p>安装好了 Tencent Serverless Toolkit for VS Code 插件，接着新建一个 python 环境下的 demo 云函数</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590202785385-16206.jpg\" alt=\"demo\"></p>\n<p>再来看下 template.yamal 文件里的函数配置</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"89162126773694400000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`Resources:\n  default:\n    Type: 'TencentCloud::Serverless::Namespace'\n    demo:\n      Properties:\n        CodeUri: ./\n        Description: This is a template function\n        Environment:\n          Variables:\n            ENV_FIRST: env1\n            ENV_SECOND: env2\n        Handler: index.main_handler\n        MemorySize: 128\n        Timeout: 3\n        Role: QCS_SCFExcuteRole\n        Runtime: Python3.6\n        # VpcConfig:\n        #   VpcId: 'vpc-qdqc5k2p'\n        #   SubnetId: 'subnet-pad6l61i'\n        # Events:\n        #   timer:\n        #     Type: Timer\n        #     Properties:\n        #       CronExpression: '*/5 * * * *'\n        #       Enable: True\n        #   cli-appid.cos.ap-beijing.myqcloud.com: # full bucket name\n        #     Type: COS\n        #     Properties:\n        #       Bucket: cli-appid.cos.ap-beijing.myqcloud.com\n        #       Filter:\n        #         Prefix: filterdir/\n        #         Suffix: .jpg\n        #       Events: cos:ObjectCreated:*\n        #       Enable: True\n        #   topic:            # topic name\n        #     Type: CMQ\n        #     Properties:\n        #       Name: qname\n        #   hello_world_apigw:  # \\${FunctionName} + '_apigw'\n        #     Type: APIGW\n        #     Properties:\n        #       StageName: release\n        #       ServiceId:\n        #       HttpMethod: ANY\n      Type: 'TencentCloud::Serverless::Function'\nGlobals:\n  Function:\n    Timeout: 10`, `89162126773694400000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">Resources<span class=\"token punctuation\">:</span>\n  <span class=\"token keyword\">default</span><span class=\"token punctuation\">:</span>\n    Type<span class=\"token punctuation\">:</span> <span class=\"token string\">'TencentCloud::Serverless::Namespace'</span>\n    demo<span class=\"token punctuation\">:</span>\n      Properties<span class=\"token punctuation\">:</span>\n        CodeUri<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span><span class=\"token operator\">/</span>\n        Description<span class=\"token punctuation\">:</span> This is a template <span class=\"token keyword\">function</span>\n        Environment<span class=\"token punctuation\">:</span>\n          Variables<span class=\"token punctuation\">:</span>\n            <span class=\"token constant\">ENV_FIRST</span><span class=\"token punctuation\">:</span> env1\n            <span class=\"token constant\">ENV_SECOND</span><span class=\"token punctuation\">:</span> env2\n        Handler<span class=\"token punctuation\">:</span> index<span class=\"token punctuation\">.</span>main_handler\n        MemorySize<span class=\"token punctuation\">:</span> <span class=\"token number\">128</span>\n        Timeout<span class=\"token punctuation\">:</span> <span class=\"token number\">3</span>\n        Role<span class=\"token punctuation\">:</span> QCS_SCFExcuteRole\n        Runtime<span class=\"token punctuation\">:</span> Python3<span class=\"token punctuation\">.</span><span class=\"token number\">6</span>\n        # VpcConfig<span class=\"token punctuation\">:</span>\n        #   VpcId<span class=\"token punctuation\">:</span> <span class=\"token string\">'vpc-qdqc5k2p'</span>\n        #   SubnetId<span class=\"token punctuation\">:</span> <span class=\"token string\">'subnet-pad6l61i'</span>\n        # Events<span class=\"token punctuation\">:</span>\n        #   timer<span class=\"token punctuation\">:</span>\n        #     Type<span class=\"token punctuation\">:</span> Timer\n        #     Properties<span class=\"token punctuation\">:</span>\n        #       CronExpression<span class=\"token punctuation\">:</span> <span class=\"token string\">'*/5 * * * *'</span>\n        #       Enable<span class=\"token punctuation\">:</span> True\n        #   cli<span class=\"token operator\">-</span>appid<span class=\"token punctuation\">.</span>cos<span class=\"token punctuation\">.</span>ap<span class=\"token operator\">-</span>beijing<span class=\"token punctuation\">.</span>myqcloud<span class=\"token punctuation\">.</span>com<span class=\"token punctuation\">:</span> # full bucket name\n        #     Type<span class=\"token punctuation\">:</span> <span class=\"token constant\">COS</span>\n        #     Properties<span class=\"token punctuation\">:</span>\n        #       Bucket<span class=\"token punctuation\">:</span> cli<span class=\"token operator\">-</span>appid<span class=\"token punctuation\">.</span>cos<span class=\"token punctuation\">.</span>ap<span class=\"token operator\">-</span>beijing<span class=\"token punctuation\">.</span>myqcloud<span class=\"token punctuation\">.</span>com\n        #       Filter<span class=\"token punctuation\">:</span>\n        #         Prefix<span class=\"token punctuation\">:</span> filterdir<span class=\"token operator\">/</span>\n        #         Suffix<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span>jpg\n        #       Events<span class=\"token punctuation\">:</span> cos<span class=\"token punctuation\">:</span>ObjectCreated<span class=\"token punctuation\">:</span><span class=\"token operator\">*</span>\n        #       Enable<span class=\"token punctuation\">:</span> True\n        #   topic<span class=\"token punctuation\">:</span>            # topic name\n        #     Type<span class=\"token punctuation\">:</span> <span class=\"token constant\">CMQ</span>\n        #     Properties<span class=\"token punctuation\">:</span>\n        #       Name<span class=\"token punctuation\">:</span> qname\n        #   hello_world_apigw<span class=\"token punctuation\">:</span>  # $<span class=\"token punctuation\">{</span>FunctionName<span class=\"token punctuation\">}</span> <span class=\"token operator\">+</span> <span class=\"token string\">'_apigw'</span>\n        #     Type<span class=\"token punctuation\">:</span> <span class=\"token constant\">APIGW</span>\n        #     Properties<span class=\"token punctuation\">:</span>\n        #       StageName<span class=\"token punctuation\">:</span> release\n        #       ServiceId<span class=\"token punctuation\">:</span>\n        #       HttpMethod<span class=\"token punctuation\">:</span> <span class=\"token constant\">ANY</span>\n      Type<span class=\"token punctuation\">:</span> <span class=\"token string\">'TencentCloud::Serverless::Function'</span>\nGlobals<span class=\"token punctuation\">:</span>\n  Function<span class=\"token punctuation\">:</span>\n    Timeout<span class=\"token punctuation\">:</span> <span class=\"token number\">10</span></code></pre></div>\n<p>OK，这样我们就创建好了一个新的云函数，下面开始编写业务逻辑。</p>\n<p>首先我们来看一下函数上线后，通过 Timer 或者 Api 网关触发函数时，<code class=\"language-text\">main\\_handler(event, context)</code> 入口函数里的 event 长啥样？</p>\n<p>假设我们通过访问 api 网关</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"69427760029398900000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`https://service-xxxxx-66666666.sh.apigw.tencentcs.com/release/demo?key=叶问`, `69427760029398900000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">https<span class=\"token punctuation\">:</span><span class=\"token operator\">/</span><span class=\"token operator\">/</span>service<span class=\"token operator\">-</span>xxxxx<span class=\"token operator\">-</span><span class=\"token number\">66666666.</span>sh<span class=\"token punctuation\">.</span>apigw<span class=\"token punctuation\">.</span>tencentcs<span class=\"token punctuation\">.</span>com<span class=\"token operator\">/</span>release<span class=\"token operator\">/</span>demo<span class=\"token operator\">?</span>key<span class=\"token operator\">=</span>叶问</code></pre></div>\n<p>POST 提交了</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"98568476563163250000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`我是请求体`, `98568476563163250000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">我是请求体</code></pre></div>\n<p>来触发云函数，那么通过打印 event 变量我们发现，这里的 event 大概长这个模样，它是一个 map</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590202785707-16206.jpg\" alt=\"event\"></p>\n<p>这样的话我们就可以得到以下对应关系</p>\n<table>\n<thead>\n<tr>\n<th align=\"left\">结果</th>\n<th align=\"left\">对应值</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td align=\"left\">请求方法</td>\n<td align=\"left\">event['httpMethod']</td>\n</tr>\n<tr>\n<td align=\"left\">请求头</td>\n<td align=\"left\">event['header']</td>\n</tr>\n<tr>\n<td align=\"left\">请求体</td>\n<td align=\"left\">event['body']</td>\n</tr>\n<tr>\n<td align=\"left\">链接内请求参数</td>\n<td align=\"left\">event['queryString']</td>\n</tr>\n<tr>\n<td align=\"left\">请求来源IP地址</td>\n<td align=\"left\">event['requestContext']['sourceip']</td>\n</tr>\n<tr>\n<td align=\"left\">定时器触发时间戳</td>\n<td align=\"left\">event['Time']</td>\n</tr>\n</tbody>\n</table>\n<p>注意，API 网关触发函数时 event 里没有 Time 键值对这一项，这一点可以用来鉴别云函数是否是通过 Timer 定时器触发的</p>\n<p>OK，知道 event 长啥样之后我们就可以解析前端发过来的请求，然后根据请求的参数返回结果了，但是需要注意的是，我们需要按照特定的格式给前端返回数据（API 网关需要开启响应集成）。</p>\n<p>假设我们要返回一段 json 数据</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"8362112024877866000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`json = {\n    &quot;flag&quot;:&quot;true&quot;,\n    &quot;message&quot;:&quot;请求成功&quot;\n}`, `8362112024877866000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">json <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span>\n    <span class=\"token string\">\"flag\"</span><span class=\"token punctuation\">:</span><span class=\"token string\">\"true\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token string\">\"message\"</span><span class=\"token punctuation\">:</span><span class=\"token string\">\"请求成功\"</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>现在来定义一个函数处理一下返回数据的格式</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"10512411582855074000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`def apiReply(reply, code=200):\n    return {\n        &quot;isBase64Encoded&quot;: False,\n        &quot;statusCode&quot;: code,\n        &quot;headers&quot;: {'Content-Type': 'application/json', &quot;Access-Control-Allow-Origin&quot;: &quot;*&quot;},\n        &quot;body&quot;: json.dumps(reply, ensure_ascii=False)\n    }`, `10512411582855074000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">def <span class=\"token function\">apiReply</span><span class=\"token punctuation\">(</span>reply<span class=\"token punctuation\">,</span> code<span class=\"token operator\">=</span><span class=\"token number\">200</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">return</span> <span class=\"token punctuation\">{</span>\n        <span class=\"token string\">\"isBase64Encoded\"</span><span class=\"token punctuation\">:</span> False<span class=\"token punctuation\">,</span>\n        <span class=\"token string\">\"statusCode\"</span><span class=\"token punctuation\">:</span> code<span class=\"token punctuation\">,</span>\n        <span class=\"token string\">\"headers\"</span><span class=\"token punctuation\">:</span> <span class=\"token punctuation\">{</span><span class=\"token string\">'Content-Type'</span><span class=\"token punctuation\">:</span> <span class=\"token string\">'application/json'</span><span class=\"token punctuation\">,</span> <span class=\"token string\">\"Access-Control-Allow-Origin\"</span><span class=\"token punctuation\">:</span> <span class=\"token string\">\"*\"</span><span class=\"token punctuation\">}</span><span class=\"token punctuation\">,</span>\n        <span class=\"token string\">\"body\"</span><span class=\"token punctuation\">:</span> json<span class=\"token punctuation\">.</span><span class=\"token function\">dumps</span><span class=\"token punctuation\">(</span>reply<span class=\"token punctuation\">,</span> ensure_ascii<span class=\"token operator\">=</span>False<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">}</span></code></pre></div>\n<p>'Content-Type': 'application/json' 声明我们返回的数据格式是json</p>\n<p>\"Access-Control-Allow-Origin\": \"*\" 声明我们返回的数据是允许跨域调用的</p>\n<p>json.dumps() 将我们要返回的 json 对象（一个 map）转成字符串</p>\n<p>ensure_ascii=False 是为了防止 json 中的中文在 json.dumps 之后乱码</p>\n<p><img src=\"https://img.serverlesscloud.cn/202063/1591167832655-kikunlj6ou.png\" alt=\"修改后的 index.py\"></p>\n<p>之后网页前端就可以拿到我们返回的 json 了</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"59984736754503480000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`{\n    &quot;flag&quot;:&quot;true&quot;,\n    &quot;message&quot;:&quot;请求成功&quot;\n}`, `59984736754503480000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"><span class=\"token punctuation\">{</span>\n    <span class=\"token string\">\"flag\"</span><span class=\"token punctuation\">:</span><span class=\"token string\">\"true\"</span><span class=\"token punctuation\">,</span>\n    <span class=\"token string\">\"message\"</span><span class=\"token punctuation\">:</span><span class=\"token string\">\"请求成功\"</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>当然一个完整的后端是需要数据的增删查改功能的，这里刚好我也需要做一个搜索黑名单的功能。</p>\n<p>（有些影视资源可能是侵犯版权的，我们要第一时间给予下架，保护正版，打击盗版）</p>\n<p>考虑到搜索关键词黑名单管理起来比较简单，这里我们直接接入腾讯云 COS<a href=\"https://cloud.tencent.com/product/cos?from=10680\">对象存储</a>来读写黑名单</p>\n<p>相关代码如下</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"94357303443429160000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`# 是否开启本地debug模式\ndebug = False\n\n# 腾讯云对象存储依赖\nif debug:\n    from qcloud_cos import CosConfig\n    from qcloud_cos import CosS3Client\n    from qcloud_cos import CosServiceError\n    from qcloud_cos import CosClientError\nelse:\n    from qcloud_cos_v5 import CosConfig\n    from qcloud_cos_v5 import CosS3Client\n    from qcloud_cos_v5 import CosServiceError\n    from qcloud_cos_v5 import CosClientError\n\n# 配置存储桶\nappid = '66666666666'\nsecret_id = u'xxxxxxxxxxxxxxx'\nsecret_key = u'xxxxxxxxxxxxxxx'\nregion = u'ap-chongqing'\nbucket = 'name'+'-'+appid\n\n# 对象存储实例\nconfig = CosConfig(Secret_id=secret_id, Secret_key=secret_key, Region=region)\nclient = CosS3Client(config)\n\n# cos 文件读写\ndef cosRead(key):\n    try:\n        response = client.get_object(Bucket=bucket, Key=key)\n        txtBytes = response['Body'].get_raw_stream()\n        return txtBytes.read().decode()\n    except CosServiceError as e:\n        return &quot;&quot;\n\ndef cosWrite(key, txt):\n    try:\n        response = client.put_object(\n            Bucket=bucket,\n            Body=txt.encode(encoding=&quot;utf-8&quot;),\n            Key=key,\n        )\n        return True\n    except CosServiceError as e:\n        return False`, `94357303443429160000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\"># 是否开启本地debug模式\ndebug <span class=\"token operator\">=</span> False\n\n# 腾讯云对象存储依赖\n<span class=\"token keyword\">if</span> debug<span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">from</span> qcloud_cos <span class=\"token keyword\">import</span> CosConfig\n    <span class=\"token keyword\">from</span> qcloud_cos <span class=\"token keyword\">import</span> CosS3Client\n    <span class=\"token keyword\">from</span> qcloud_cos <span class=\"token keyword\">import</span> CosServiceError\n    <span class=\"token keyword\">from</span> qcloud_cos <span class=\"token keyword\">import</span> CosClientError\n<span class=\"token keyword\">else</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosConfig\n    <span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosS3Client\n    <span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosServiceError\n    <span class=\"token keyword\">from</span> qcloud_cos_v5 <span class=\"token keyword\">import</span> CosClientError\n\n# 配置存储桶\nappid <span class=\"token operator\">=</span> <span class=\"token string\">'66666666666'</span>\nsecret_id <span class=\"token operator\">=</span> u<span class=\"token string\">'xxxxxxxxxxxxxxx'</span>\nsecret_key <span class=\"token operator\">=</span> u<span class=\"token string\">'xxxxxxxxxxxxxxx'</span>\nregion <span class=\"token operator\">=</span> u<span class=\"token string\">'ap-chongqing'</span>\nbucket <span class=\"token operator\">=</span> <span class=\"token string\">'name'</span><span class=\"token operator\">+</span><span class=\"token string\">'-'</span><span class=\"token operator\">+</span>appid\n\n# 对象存储实例\nconfig <span class=\"token operator\">=</span> <span class=\"token function\">CosConfig</span><span class=\"token punctuation\">(</span>Secret_id<span class=\"token operator\">=</span>secret_id<span class=\"token punctuation\">,</span> Secret_key<span class=\"token operator\">=</span>secret_key<span class=\"token punctuation\">,</span> Region<span class=\"token operator\">=</span>region<span class=\"token punctuation\">)</span>\nclient <span class=\"token operator\">=</span> <span class=\"token function\">CosS3Client</span><span class=\"token punctuation\">(</span>config<span class=\"token punctuation\">)</span>\n\n# cos 文件读写\ndef <span class=\"token function\">cosRead</span><span class=\"token punctuation\">(</span>key<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">try</span><span class=\"token punctuation\">:</span>\n        response <span class=\"token operator\">=</span> client<span class=\"token punctuation\">.</span><span class=\"token function\">get_object</span><span class=\"token punctuation\">(</span>Bucket<span class=\"token operator\">=</span>bucket<span class=\"token punctuation\">,</span> Key<span class=\"token operator\">=</span>key<span class=\"token punctuation\">)</span>\n        txtBytes <span class=\"token operator\">=</span> response<span class=\"token punctuation\">[</span><span class=\"token string\">'Body'</span><span class=\"token punctuation\">]</span><span class=\"token punctuation\">.</span><span class=\"token function\">get_raw_stream</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> txtBytes<span class=\"token punctuation\">.</span><span class=\"token function\">read</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">.</span><span class=\"token function\">decode</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    except CosServiceError <span class=\"token keyword\">as</span> e<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> <span class=\"token string\">\"\"</span>\n\ndef <span class=\"token function\">cosWrite</span><span class=\"token punctuation\">(</span>key<span class=\"token punctuation\">,</span> txt<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    <span class=\"token keyword\">try</span><span class=\"token punctuation\">:</span>\n        response <span class=\"token operator\">=</span> client<span class=\"token punctuation\">.</span><span class=\"token function\">put_object</span><span class=\"token punctuation\">(</span>\n            Bucket<span class=\"token operator\">=</span>bucket<span class=\"token punctuation\">,</span>\n            Body<span class=\"token operator\">=</span>txt<span class=\"token punctuation\">.</span><span class=\"token function\">encode</span><span class=\"token punctuation\">(</span>encoding<span class=\"token operator\">=</span><span class=\"token string\">\"utf-8\"</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">,</span>\n            Key<span class=\"token operator\">=</span>key<span class=\"token punctuation\">,</span>\n        <span class=\"token punctuation\">)</span>\n        <span class=\"token keyword\">return</span> True\n    except CosServiceError <span class=\"token keyword\">as</span> e<span class=\"token punctuation\">:</span>\n        <span class=\"token keyword\">return</span> False</code></pre></div>\n<p>这里需要注意一点，我在本地 python 环境安装的腾讯云对象存储依赖库是 <code class=\"language-text\">qcloud\\_cos</code>，但是在云函数在线运行环境中，已经安装的是 <code class=\"language-text\">qcloud\\_cos\\_v5</code> 的依赖库，</p>\n<p>为了方便本地调试，这里我设置了一个 debug 开关，来动态导入 <code class=\"language-text\">qcloud\\_cos</code> 依赖。这样我们现在就可以读写 cos 存储桶里的文件了，像黑名单这种数据可以直接保存成文本，每行记录一个黑名单关键词即可，用的时候可以按行分割成黑名单 List，也可以直接判断黑名单中是否有当前请求的关键词。</p>\n<p>这样我们就实现了后端云函数的数据存取问题，不过这种方法也有一些缺点，比如不方便更改数据等。这里我建议大家可以把数据处理成 map 键值对，然后使用 <code class=\"language-text\">json.dumps</code> 转成字符串存储到 cos 存储桶里，</p>\n<p>这样最大的好处就是在后面用到之前的数据时可以直接 json.loads 加载回来，方便增删查改数据（对应 map 键值的增删查改）</p>\n<p>例如</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"8692343353645771000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`def getBlacks():\n    blackMap = {}\n    blackTxt = cosRead('blacks.txt')  # 读取数据\n    if len(blackTxt) > 0:\n        blackMap = json.loads(blackTxt)\n    return blackMap\n\ndef addBlacks(black):\n    blackMap = getBlacks()\n    if len(blackMap) > 0:\n        blackMap[black]='我是黑名单'\n    return cosWrite('blacks.txt', json.dumps(blackMap, ensure_ascii=False)) if len(blackMap) > 0 else False\n\n\ndef delBlacks(black):\n    blackMap = getBlacks()\n    if len(blackMap) > 0:\n        blackMap.pop(black)\n    return cosWrite('blacks.txt', json.dumps(blackMap, ensure_ascii=False)) if len(blackMap) > 0 else False`, `8692343353645771000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">def <span class=\"token function\">getBlacks</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    blackMap <span class=\"token operator\">=</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span>\n    blackTxt <span class=\"token operator\">=</span> <span class=\"token function\">cosRead</span><span class=\"token punctuation\">(</span><span class=\"token string\">'blacks.txt'</span><span class=\"token punctuation\">)</span>  # 读取数据\n    <span class=\"token keyword\">if</span> <span class=\"token function\">len</span><span class=\"token punctuation\">(</span>blackTxt<span class=\"token punctuation\">)</span> <span class=\"token operator\">></span> <span class=\"token number\">0</span><span class=\"token punctuation\">:</span>\n        blackMap <span class=\"token operator\">=</span> json<span class=\"token punctuation\">.</span><span class=\"token function\">loads</span><span class=\"token punctuation\">(</span>blackTxt<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> blackMap\n\ndef <span class=\"token function\">addBlacks</span><span class=\"token punctuation\">(</span>black<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    blackMap <span class=\"token operator\">=</span> <span class=\"token function\">getBlacks</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">if</span> <span class=\"token function\">len</span><span class=\"token punctuation\">(</span>blackMap<span class=\"token punctuation\">)</span> <span class=\"token operator\">></span> <span class=\"token number\">0</span><span class=\"token punctuation\">:</span>\n        blackMap<span class=\"token punctuation\">[</span>black<span class=\"token punctuation\">]</span><span class=\"token operator\">=</span><span class=\"token string\">'我是黑名单'</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">cosWrite</span><span class=\"token punctuation\">(</span><span class=\"token string\">'blacks.txt'</span><span class=\"token punctuation\">,</span> json<span class=\"token punctuation\">.</span><span class=\"token function\">dumps</span><span class=\"token punctuation\">(</span>blackMap<span class=\"token punctuation\">,</span> ensure_ascii<span class=\"token operator\">=</span>False<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">if</span> <span class=\"token function\">len</span><span class=\"token punctuation\">(</span>blackMap<span class=\"token punctuation\">)</span> <span class=\"token operator\">></span> <span class=\"token number\">0</span> <span class=\"token keyword\">else</span> False\n\n\ndef <span class=\"token function\">delBlacks</span><span class=\"token punctuation\">(</span>black<span class=\"token punctuation\">)</span><span class=\"token punctuation\">:</span>\n    blackMap <span class=\"token operator\">=</span> <span class=\"token function\">getBlacks</span><span class=\"token punctuation\">(</span><span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">if</span> <span class=\"token function\">len</span><span class=\"token punctuation\">(</span>blackMap<span class=\"token punctuation\">)</span> <span class=\"token operator\">></span> <span class=\"token number\">0</span><span class=\"token punctuation\">:</span>\n        blackMap<span class=\"token punctuation\">.</span><span class=\"token function\">pop</span><span class=\"token punctuation\">(</span>black<span class=\"token punctuation\">)</span>\n    <span class=\"token keyword\">return</span> <span class=\"token function\">cosWrite</span><span class=\"token punctuation\">(</span><span class=\"token string\">'blacks.txt'</span><span class=\"token punctuation\">,</span> json<span class=\"token punctuation\">.</span><span class=\"token function\">dumps</span><span class=\"token punctuation\">(</span>blackMap<span class=\"token punctuation\">,</span> ensure_ascii<span class=\"token operator\">=</span>False<span class=\"token punctuation\">)</span><span class=\"token punctuation\">)</span> <span class=\"token keyword\">if</span> <span class=\"token function\">len</span><span class=\"token punctuation\">(</span>blackMap<span class=\"token punctuation\">)</span> <span class=\"token operator\">></span> <span class=\"token number\">0</span> <span class=\"token keyword\">else</span> False</code></pre></div>\n<h3 id=\"3-云函数上线发布\"><a href=\"#3-%E4%BA%91%E5%87%BD%E6%95%B0%E4%B8%8A%E7%BA%BF%E5%8F%91%E5%B8%83\" aria-label=\"3 云函数上线发布 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>3. 云函数上线发布</h3>\n<p>OK，终于来到最后一步了，下面我们再去看一下前面提到的 template.yaml 云函数配置文件</p>\n<div\n              class=\"gatsby-code-button-container\"\n              data-toaster-id=\"74783097829773790000\"\n              data-toaster-class=\"gatsby-code-button-toaster\"\n              data-toaster-text-class=\"gatsby-code-button-toaster-text\"\n              data-toaster-text=\"代码复制成功\"\n              data-toaster-duration=\"3500\"\n              onClick=\"copyToClipboard(`Resources:\n  default:\n    Type: 'TencentCloud::Serverless::Namespace'\n    demo:\n      Properties:\n        CodeUri: ./\n        Type: Event\n        Environment:\n          Variables:\n        Description: 这是一个测试函数\n        Handler: index.main_handler\n        MemorySize: 64\n        Timeout: 3\n        Runtime: Python3.6\n        Events:\n          demo_apigw:  # \\${FunctionName} + '_apigw'\n            Type: APIGW\n            Properties:\n              StageName: release\n              ServiceId:\n              HttpMethod: ANY\n      Type: 'TencentCloud::Serverless::Function'`, `74783097829773790000`)\"\n            >\n              <div\n                class=\"gatsby-code-button\"\n                data-tooltip=\"\"\n              >\n                复制代码<svg class=\"gatsby-code-button-icon\" xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\"><path fill=\"none\" d=\"M0 0h24v24H0V0z\"/><path d=\"M16 1H2v16h2V3h12V1zm-1 4l6 6v12H6V5h9zm-1 7h5.5L14 6.5V12z\"/></svg>\n              </div>\n            </div>\n<div class=\"gatsby-highlight\" data-language=\"javascript\"><pre class=\"language-javascript\"><code class=\"language-javascript\">Resources<span class=\"token punctuation\">:</span>\n  <span class=\"token keyword\">default</span><span class=\"token punctuation\">:</span>\n    Type<span class=\"token punctuation\">:</span> <span class=\"token string\">'TencentCloud::Serverless::Namespace'</span>\n    demo<span class=\"token punctuation\">:</span>\n      Properties<span class=\"token punctuation\">:</span>\n        CodeUri<span class=\"token punctuation\">:</span> <span class=\"token punctuation\">.</span><span class=\"token operator\">/</span>\n        Type<span class=\"token punctuation\">:</span> Event\n        Environment<span class=\"token punctuation\">:</span>\n          Variables<span class=\"token punctuation\">:</span>\n        Description<span class=\"token punctuation\">:</span> 这是一个测试函数\n        Handler<span class=\"token punctuation\">:</span> index<span class=\"token punctuation\">.</span>main_handler\n        MemorySize<span class=\"token punctuation\">:</span> <span class=\"token number\">64</span>\n        Timeout<span class=\"token punctuation\">:</span> <span class=\"token number\">3</span>\n        Runtime<span class=\"token punctuation\">:</span> Python3<span class=\"token punctuation\">.</span><span class=\"token number\">6</span>\n        Events<span class=\"token punctuation\">:</span>\n          demo_apigw<span class=\"token punctuation\">:</span>  # $<span class=\"token punctuation\">{</span>FunctionName<span class=\"token punctuation\">}</span> <span class=\"token operator\">+</span> <span class=\"token string\">'_apigw'</span>\n            Type<span class=\"token punctuation\">:</span> <span class=\"token constant\">APIGW</span>\n            Properties<span class=\"token punctuation\">:</span>\n              StageName<span class=\"token punctuation\">:</span> release\n              ServiceId<span class=\"token punctuation\">:</span>\n              HttpMethod<span class=\"token punctuation\">:</span> <span class=\"token constant\">ANY</span>\n      Type<span class=\"token punctuation\">:</span> <span class=\"token string\">'TencentCloud::Serverless::Function'</span></code></pre></div>\n<p>可以看到，这里我们已经配置好了 API 网关触发器，如果你们没有创建过 API 网关的话，这里 ServiceId 可以先留空，记得等云函数上传发布成功后在腾讯云控制台拿到 ServiceId 再填上就好了</p>\n<p><img src=\"https://ask.qcloudimg.com/http-save/yehe-1361327/09s73o9lba.png?imageView2/2/w/1620\" alt=\"上传云函数\"></p>\n<p>云函上传成功后会有提示，并帮我们自动创建了 API 网关触发器</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590202785362-16206.jpg\" alt=\"上传成功\"></p>\n<p>这里我们登录腾讯云控制台去看一下云函数有没有创建好，顺便配置一下 API 网关</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590202785741-16206.jpg\" alt=\"云函数触发方式\"></p>\n<p>现在我们就可以把生成的 ServiceId 填到本地的云函数配置文件里了，不然下次上传云函数系统还会自动帮我们新建 API 网关，然后我们先打开最底下那个蓝色的访问路径看下返回了什么</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590202785943-16206.jpg\" alt=\"未开启响应集成前返回的数据\"></p>\n<p>可以看到，云函数响应了我们 <code class=\"language-text\">main\\_handler</code> 函数返回的 map 数据，不过我们想要的只是 body 部分，headers 之类的是要告诉浏览器的，这是因为我们的 API 网关还没有开启响应集成，下面打开云函数触发方式页面的第一个蓝色的箭头，转到 API 网关管理页面，选择编辑。</p>\n<p>找到 demo 的 API 然后点击右边的编辑按钮</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590202785926-16206.jpg\" alt=\"启用响应集成\"></p>\n<p>然后来到第二步，勾选启用响应集成选项后点击下一步保存</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590202785701-16206.jpg\" alt=\"发布页\"></p>\n<p>回到发布页点击右上角发布，填写备注后，点击提交即可。</p>\n<p><img src=\"https://img.serverlesscloud.cn/2020523/1590202785364-16206.jpg\" alt=\"正常返回\"></p>\n<p>我们这次再刷新一下网页就可以正常返回数据了。</p>\n<h2 id=\"写在最后\"><a href=\"#%E5%86%99%E5%9C%A8%E6%9C%80%E5%90%8E\" aria-label=\"写在最后 permalink\" class=\"anchor\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>写在最后</h2>\n<p>看到这里想必你已经学会使用腾讯云 SCF+COS 快速开发自己的后端 API，加速全栈应用的开发了。</p>\n<p>耶( •̀ ω •́ )y</p>\n<hr>\n<div id='scf-deploy-iframe-or-md'></div>\n<hr>\n<blockquote>\n<p><strong>传送门：</strong></p>\n<ul>\n<li>GitHub: <a href=\"https://github.com/serverless/serverless/blob/master/README_CN.md\">github.com/serverless</a></li>\n<li>官网：<a href=\"https://serverless.com/\">serverless.com</a></li>\n</ul>\n</blockquote>\n<p>欢迎访问：<a href=\"https://serverlesscloud.cn/\">Serverless 中文网</a>，您可以在 <a href=\"https://serverlesscloud.cn/best-practice\">最佳实践</a> 里体验更多关于 Serverless 应用的开发！</p>","tableOfContents":"<ul>\n<li><a href=\"/blog/2020-04-23-serverless-scf-cos/#%E6%95%88%E6%9E%9C%E5%B1%95%E7%A4%BA\">效果展示</a></li>\n<li><a href=\"/blog/2020-04-23-serverless-scf-cos/#%E5%89%8D%E7%AB%AF%E9%83%A8%E5%88%86\">前端部分</a></li>\n<li>\n<p><a href=\"/blog/2020-04-23-serverless-scf-cos/#%E5%90%8E%E7%AB%AF%E9%83%A8%E5%88%86\">后端部分</a></p>\n<ul>\n<li><a href=\"/blog/2020-04-23-serverless-scf-cos/#1-%E5%AE%89%E8%A3%85-tencent-serverless-toolkit-for-vs-code\">1. 安装 Tencent Serverless Toolkit for VS Code</a></li>\n<li><a href=\"/blog/2020-04-23-serverless-scf-cos/#2-%E7%BC%96%E5%86%99%E4%BA%91%E5%87%BD%E6%95%B0\">2. 编写云函数</a></li>\n<li><a href=\"/blog/2020-04-23-serverless-scf-cos/#3-%E4%BA%91%E5%87%BD%E6%95%B0%E4%B8%8A%E7%BA%BF%E5%8F%91%E5%B8%83\">3. 云函数上线发布</a></li>\n</ul>\n</li>\n<li><a href=\"/blog/2020-04-23-serverless-scf-cos/#%E5%86%99%E5%9C%A8%E6%9C%80%E5%90%8E\">写在最后</a></li>\n</ul>"},"previousBlog":{"id":"5c34df1d-ef7f-5467-afe7-d0a28d5e8990","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020523/1590213128368-16200.jpg","authors":["乂乂又又"],"categories":["user-stories"],"date":"2020-04-23T00:00:00.000Z","title":"万物皆可 Serverless 之云函数 SCF+Kaggle 端到端验证码识别从训练到部署","description":"今天本文就尝试带大家借助 Kaggle+SCF，快速训练部署一个端到端的通用验证码识别模型，真正的验证码识别从入门到应用的一条龙服务。","authorslink":["https://cloud.tencent.com/developer/article/1618583"],"translators":null,"translatorslink":null,"tags":["云函数","Kaggle"],"keywords":"Serverless,Serverless AI,Serverless应用","outdated":null},"wordCount":{"words":322,"sentences":52,"paragraphs":49},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-04-23-serverless-kaggle-scf.md","fields":{"slug":"/blog/2020-04-23-serverless-kaggle-scf/","keywords":["go","java","python","serverless","云函数","验证码","kaggle","模型","识别","训练","serverlesscloud"]}},"nextBlog":{"id":"b14f0796-64f5-5137-96eb-9c395a6bc3ab","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020523/1590216111548-16205.jpg","authors":["乂乂又又"],"categories":["user-stories"],"date":"2020-04-23T00:00:00.000Z","title":"万物皆可 Serverless 之我的 Serverless 之路","description":"本文主要介绍我和 Serverless 的结缘之路。","authorslink":["https://cloud.tencent.com/developer/article/1618591"],"translators":null,"translatorslink":null,"tags":["Serverless","个人博客"],"keywords":"Serverless,Serverless实战,Serverless应用","outdated":null},"wordCount":{"words":548,"sentences":86,"paragraphs":85},"fileAbsolutePath":"/opt/build/repo/content/blog/2020-04-23-serverless-learn-scf.md","fields":{"slug":"/blog/2020-04-23-serverless-learn-scf/","keywords":["python","serverless","无服务器","无服务器架构","云函数","Serverless","serverless","serverlesscloud","应用"]}},"recommendBlogs":{"edges":[{"node":{"id":"4300b21c-7209-5256-86ff-0d38e3daec9b","frontmatter":{"thumbnail":"https://main.qcloudimg.com/raw/14f1c8eed372e76c1b139703b2f6d0fa.jpg","authors":["KieranMcCarthy"],"categories":["user-stories","engineering-culture"],"date":"2018-01-09T00:00:00.000Z","title":"我是如何在四年时间里，从厨师转行为 Serverless 应用开发者","description":"我是厨师出身，现在成为了一名 Serverless 应用开发者。","authorslink":["https://serverless.com/author/kieranmccarthy/"],"translators":["Aceyclee"],"translatorslink":["https://www.zhihu.com/people/Aceyclee"],"tags":["应用开发","Serverless"],"keywords":"Serverless 应用开发,Serverless 管理,厨师转行为 Serverless 应用开发者","outdated":null},"wordCount":{"words":285,"sentences":38,"paragraphs":36},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-01-09-from-chef-to-serverless-developer-in-4-years.md","fields":{"slug":"/blog/2018-01-09-from-chef-to-serverless-developer-in-4-years/","keywords":["无服务器","无服务器开发","云函数","学习","Serverless","构建","Framework","开发者","服务器","应用","学位","简历"]}}},{"node":{"id":"713a0563-4bf9-5721-bacb-3b4ef609fe4a","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/camp-fire/camp-fire-housing-thumb.jpg","authors":["EricWyne"],"categories":["guides-and-tutorials","user-stories"],"date":"2018-12-05T00:00:00.000Z","title":"Serverless Twitter 机器人帮助为坎普山火受灾者安置住房","description":"加利福尼亚州的坎普山火致使数千人流离失所，为此，我构建了一个简单的 Serverless Twitter 机器人来帮助将受灾者安置在临时住房！","authorslink":["https://serverless.com/author/ericwyne/"],"translators":["Aceyclee"],"translatorslink":["zhihu.com/people/Aceyclee"],"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":157,"sentences":26,"paragraphs":26},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-12-05-serverless-twitter-camp-fire.md","fields":{"slug":"/blog/2018-12-05-serverless-twitter-camp-fire/","keywords":["serverless","无服务器","云函数","Serverless","org","住房","Twitter","函数","受灾","机器人","山火"]}}},{"node":{"id":"98602143-b837-5f50-a24f-3b1ec76044d7","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/sqquid/sqquid-serverless-thumb.jpg","authors":["RonPeled"],"categories":["user-stories"],"date":"2018-12-17T00:00:00.000Z","title":"SQQUID：100% 无服务器初创公司","description":"SQQUID 将 AWS Lambda 和无服务器框架用于其核心产品和营销网站。我们来看看一个完全无服务器的初创公司是怎样的。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":266,"sentences":42,"paragraphs":42},"fileAbsolutePath":"/opt/build/repo/content/blog/2018-12-17-sqquid-one-hundred-percent-serverless.md","fields":{"slug":"/blog/2018-12-17-sqquid-one-hundred-percent-serverless/","keywords":["go","serverless","无服务器","无服务器架构","服务器","架构","Lambda","集成","FaaS","串行","系统"]}}},{"node":{"id":"29dc2e58-d2ba-56f9-aee1-d21b0bc62e0e","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/ao-com-story/ao-serverless-thumbnail.png","authors":["NickGottlieb"],"categories":["user-stories"],"date":"2019-04-24T00:00:00.000Z","title":"AO.com：逐渐转向无服务器优先","description":"AO.com 的 SCV 团队率先尝试无服务器服务。折服于无服务器框架的快速周转时间和低维护成本，整个团队逐渐转向无服务器优先。","authorslink":null,"translators":null,"translatorslink":null,"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":236,"sentences":42,"paragraphs":35},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-04-24-ao-serverless-first.md","fields":{"slug":"/blog/2019-04-24-ao-serverless-first/","keywords":["serverless","无服务器","服务器","团队","Lambda","功能","构建"]}}},{"node":{"id":"752d08d1-387a-5bde-acf3-98141baab294","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020414/1586871710979-%E5%85%AC%E5%85%B1%E7%94%A8.png","authors":["Anycodes"],"categories":["user-stories"],"date":"2019-06-20T00:00:00.000Z","title":"如何用 Serverless 为 Python 云函数打包依赖","description":"在使用无服务器云函数SCF时通常会遇到导入第三方库的问题，很多小伙伴比较头疼是：应该如何打包进去？这里，推荐几个不错的方法。","authorslink":["https://zhuanlan.zhihu.com/ServerlessGo"],"translators":null,"translatorslink":null,"tags":["云函数","Serverless"],"keywords":"Serverless,Serverless应用,无服务器云函数","outdated":null},"wordCount":{"words":81,"sentences":43,"paragraphs":43},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-06-20-for-python-cloud-functions.md","fields":{"slug":"/blog/2019-06-20-for-python-cloud-functions/","keywords":["java","serverless","无服务器","无服务器云函数","云函数","serverlesscloud","安装","serverless","pillowtest"]}}},{"node":{"id":"2dc78814-9d77-555b-a1bb-ad202c8ec2d1","frontmatter":{"thumbnail":"https://s3-us-west-2.amazonaws.com/assets.blog.serverless.com/cloudforecast/thumbnail.png","authors":["FrancoisLagier"],"categories":["user-stories"],"date":"2019-08-07T00:00:00.000Z","title":"Serverless：初创企业的理想选择？（CloudForecast 案例分析）","description":"CloudForecast 是 2018 年成立的一家独立初创企业，本文将介绍他们决定选择 Serverless 的原因。","authorslink":["https://serverless.com/author/francoislagier/"],"translators":["Aceyclee"],"translatorslink":["zhihu.com/people/Aceyclee"],"tags":null,"keywords":null,"outdated":null},"wordCount":{"words":211,"sentences":29,"paragraphs":29},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-08-07-serverless-for-startups.md","fields":{"slug":"/blog/2019-08-07-serverless-for-startups/","keywords":["serverless","云函数","serverless","函数","Serverless","utm","Framework","blog","CloudForecast","cloudforecast"]}}},{"node":{"id":"97450b07-658b-5207-8216-1c7b9b51b115","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020114/1578988490344-v2-8b2cd2c5275aa2c5a3c5083a148a7a9f_1200x500.jpg","authors":["Anycodes"],"categories":["user-stories"],"date":"2019-09-01T00:00:00.000Z","title":"如何通过 Serverless 与自然语言处理，让搜索引擎「看」到你的博客","description":"Serverless 与自然语言处理结合的一个小应用","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["个人博客","serverless"],"keywords":"Serverless 自然语言处理","outdated":null},"wordCount":{"words":106,"sentences":34,"paragraphs":34},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-09-01-search-engine-blog.md","fields":{"slug":"/blog/2019-09-01-search-engine-blog/","keywords":["serverless","云函数","keywords","serverlesscloud","summary"]}}},{"node":{"id":"ae4fd2f8-515c-5aec-b584-38427ef33f7e","frontmatter":{"thumbnail":"https://img.serverlesscloud.cn/2020114/1578989800047-part-00492-780.jpg","authors":["Anycodes"],"categories":["guides-and-tutorials","user-stories"],"date":"2019-09-16T00:00:00.000Z","title":"突破传统 OJ 瓶颈，「判题姬」接入云函数","description":"通过 Serverless 实现在线编程","authorslink":["https://www.zhihu.com/people/liuyu-43-97"],"translators":null,"translatorslink":null,"tags":["在线编程","云函数"],"keywords":"Serverless 在线编程,Serverless OJ","outdated":null},"wordCount":{"words":169,"sentences":30,"paragraphs":30},"fileAbsolutePath":"/opt/build/repo/content/blog/2019-09-16-online-Judge.md","fields":{"slug":"/blog/2019-09-16-online-Judge/","keywords":["python","serverless","云函数","代码","函数","serverless"]}}}],"totalCount":64}},"pageContext":{"isCreatedByStatefulCreatePages":false,"blogId":"07918513-5a0f-5c41-b33c-209be7389654","previousBlogId":"5c34df1d-ef7f-5467-afe7-d0a28d5e8990","nextBlogId":"b14f0796-64f5-5137-96eb-9c395a6bc3ab","categories":["user-stories"]}}}