本文介紹使用全靜態頁面的網站如何利用騰訊云的 SCF+API 服務實作簡單的后端介面,并提供了一個 Python 出題器的實體演示,
相關服務介紹:
云函式(Serverless Cloud Function,SCF)是騰訊云為企業和開發者們提供的無服務器執行環境,幫助您在無需購買和管理服務器的情況下運行代碼, API 網關(API Gateway)是 API 托管服務,提供 API 的完整生命周期管理,包括創建、維護、發布、運行、下線等,
前幾天為我家小盆友用 Python 寫了個簡單的自動數學題出題器,小家伙十分好奇,隔三差五的就要來讓我演示一番 ??,只是每次都要拿本出來輸命令給他看實在有些麻煩,于是想著能不能加個前端頁面呼叫,直接打開頁面就能看到運行效果,
作為一個行動派派,我目標鎖定了用 SCF+API 的方式,也就是現在很??的 serveless 方案,最大的好處當然是不用再伺候服務器了,少了很多搭建的麻煩,而且這個按實際使用量計費,對于小網站再適合不過了,
下面介紹下要怎么實作了,首先,你要有個騰訊云賬號,然后參考??的簡單步驟:
- 創建云函式 SCF,
- 創建 API Gateway,后臺指定呼叫步驟 1 建好的云函式,
- API gateway中 新建密鑰,使用計劃,實作訪問控制并發布,
- 寫前端頁面,呼叫剛寫好的 API,
- 測驗,解決各種 bug,大功告成!
創建云函式 SCF
照著這個檔案 云函式快速入門 按里面的步驟來創建自己業務函式,第一次可以選擇使用控制臺創建函式,運行環境中選擇自己熟悉的編程語言,當前支持 python, php, golang, java, nodejs 幾種,然后就可以在函式代碼下愉快的開始了,這里以運行環境 Python3.6 為例,默認的入口函式是 index.main_handler,有兩個輸入引數:
- event:可以獲取觸發源的訊息 - 主要用來獲取傳入引數,
- context:可以獲取本函式的環境及配置資訊,
不清楚引數里有什么的,或怎么用的,可以直接列印出來看看,都是 dict 型別,一目了然,建議加上傳入引數檢查和限制,畢竟我們不知道呼叫介面的人會傳些什么奇怪的東西,回傳型別包裝成 json 格式,對前端呼叫更友好,給出改好的代碼??:
# -*- coding: utf8 -*-
import sys, getopt, random
import json
def main_handler(event, context):
print("Received event: %s" % event)
print("Received context: %s" % context)
params = event["queryString"]
return auto_cal_generator(int(params["limit"]), int(params["op_count"]), params["op_type"].split(","), int(params["total"]))
def auto_cal_generator(limit=100, op_count=1, op_type=["+"], total=100):
if limit>999 or op_count>9 or total>99:
return "exceed max input limit"
res = {}
res["msg"] = "Here are today's %d works, good luck!" % total
questions = []
l = len(op_type)-1
for j in range(0, total):
up = limit
question = ""
for i in range(0, op_count+1):
num = 0
if i == 0:
num = random.randint(1,max(1,min(limit,up)))
question = "%s%d" % (question, num)
up -= num
continue
op = "+"
if limit - up > 0:
op_i = random.randint(0,l)
op = op_type[op_i]
question = "%s%s" % (question, op)
if op =="+":
num = random.randint(1,max(1,min(limit,up)))
up -= num
elif op == "-":
num = random.randint(1,max(limit-up, 1))
up += num
else:
print("operator error: %s" % op)
sys.exit(1)
question = "%s%d" % (question, num)
questions.append("%d: %s=" % (j+1, question))
res["questions"] = questions
return json.dumps(res)
寫完 code 后當然不能忘了最重要的測驗作業,代碼輸入框下就是測驗的入口,需要創建測驗模板,系統已經預置了好幾種模板型別,直接拿來改成你需要的就好,我們用 API Gateway 事件模板為原型修改剛寫好的出題器的測驗模板,由于我們 code 獲取的是 event 里的 queryString,這里只用修改里面的 queryString 這塊:
"queryString": {
"op\_type" : "+,-",
"op\_count" : 2,
"limit":100,
"total":10
},
創建完測驗模板后,點擊左側測驗,瞬間回傳結果:
回傳結果
"{\"msg\": \"Here are today's 10 works, good luck!\", \"questions\": \"1: 76-4-44=\", \"2: 52-42+67=\", \"3: 95+4-50=\", \"4: 84-78-1=\", \"5: 29-20-9=\", \"6: 19+37+38=\", \"7: 93-53+57=\", \"8: 80+7+7=\", \"9: 90-74-11=\", \"10: 7+34+52=\"}"
結果下方還有執行摘要和執行日志,方便除錯,
創建 API Gateway
云函式 SCF 寫完后,如果想要能通過網路 http(s) 請求直接訪問,就要為其添加觸發方式為 API 網關觸發器,同時強烈建議將鑒權方法置為 API 網關密鑰對,然后就會在 API Gateway 下自動創建出一個對應的 service API,這一步如果遇到權限問題無法自動創建 API 的話,也不要著急,可以直接在 API gateway 的控制臺操作,
參考:API 網關快速入門,
創建 API 時注意將鑒權型別改成密鑰對,下方有個支持CORS的選項,如果需要跨域訪問就勾上,反之可以忽略,設定完需要接收的引數后,在下一步的后端配置中選后端型別為 cloud function 后,選中剛建好的云函式,就做好了這兩者的關聯,
建好 API 后,來到對應服務下的管理 API 標簽就能看到剛建好的 API,在串列的右側有除錯入口,千萬不要忘了點進去做下測驗,測驗完成后,再到服務頁完成發布,這樣 API 就可以被訪問到了,
訪問控制
然后,就來到了相當重要但也容易被忽略的訪問控制這步,在前面我們已經選擇了密鑰對的方式作為鑒權型別,雖然有密鑰泄露的風險,但對于小網站來說這個驗證也是足夠了,記得保存好密鑰并定期修改就好,
之后的步驟就是創建密鑰對,創建使用計劃系結密鑰對,再把使用計劃系結服務或 API,下面直接甩出檔案:使用計劃,使用計劃中除了可以系結密鑰對,還可以進行流量控制,可按需設定,
前端呼叫
配置完后端服務后,要解決的就是訪問的問題了,由于沒錢供服務器,用的是靜態頁面托管的方式建的站,前端直接 ajax 訪問 API 來獲取結果,參考檔案在此:密鑰對認證,如何生成簽名(里面給出了用不同語言生成簽名的例子),
由于沒寫前端好多年,對前端的認知還停留在 js 和 jquery 階段,這里只能給出改好的 jquery 寫法,用的是 crypto-js 加密,
//<script src=https://www.cnblogs.com/serverlesscloud/p/"https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.0.0/crypto-js.min.js"></script>
function getHeader(){
var nowDate = new Date();
var dateTime = nowDate.toGMTString();
var SecretId ='****';
var SecretKey = '****';
var source = 'your_source';
var auth = "hmac id=\"" + SecretId + "\", algorithm=\"hmac-sha1\", headers=\"x-date source\", signature=\"";
var signStr = "x-date: " + dateTime + "\n" + "source: " + source;
var sign = CryptoJS.HmacSHA1(signStr, SecretKey)
sign = CryptoJS.enc.Base64.stringify(sign)
sign = auth + sign + "\""
var header = {"Source": source , "X-Date": dateTime , "Authorization":sign}
return header
}
function getQ(){
$.ajax({
url: "https://xxxx/xx",
type: "get",
data:{
"op_count" : 1,
"op_type" : "+,-",
"limit" : 100,
"total" : 10
},
dataType: "json",
crossDomain: true,
headers: getHeader(),
success: function (data) {
if (data.errorCode < 0){
//deal function error: data.errorMessage
return
}
data= https://www.cnblogs.com/serverlesscloud/p/$.parseJSON(data);
//show result in page
},
error: function(jqXHR, textStatus, errorThrown){
//deal api error
}
})
}
如果在前面創建 API gateway 的 service 時候沒有指定自定義域名,或是自定義域名和呼叫頁面的域名不是同一個,就會涉及到跨域的問題,解決跨域問題傳統的方法可以用 jsonp,但它沒辦法在 request 的 Header 里加引數,也就傳不了鑒權所需的欄位,所以這里只能用 CORS 來解決跨域:
對于服務端,只要前面建 API 的時候勾選了支持 CORS 選項,就會自動開啟,參考 API 控制臺相關問題 ,對于客戶端,在 ajax 引數中設定 crossDomain: true 就可以了,
完成
最后,解決一下頁面上的 bug,測驗通過后就大功告成了!給出演示地址:演示,還加上了列印功能,不用再復制粘貼了??
One More Thing
3 秒你能做什么?喝一口水,看一封郵件,還是 —— 部署一個完整的 Serverless 應用?
復制鏈接至 PC 瀏覽器訪問:https://serverless.cloud.tencent.com/deploy/express
3 秒極速部署,立即體驗史上最快的 Serverless HTTP 實戰開發!
傳送門:
- GitHub: github.com/serverless
- 官網:serverless.com
歡迎訪問:Serverless 中文網,您可以在 最佳實踐 里體驗更多關于 Serverless 應用的開發!
推薦閱讀:《Serverless 架構:從原理、設計到專案實戰》
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/79627.html
標籤:其他
上一篇:2020年6月Microsoft 365 新功能速遞
下一篇:kubectl cp 命令使用
