专栏首页cloud【玩转腾讯云】静态网站利用SCF+API访问自定义后端接口
原创

【玩转腾讯云】静态网站利用SCF+API访问自定义后端接口

本文介绍使用全静态页面的网站如何利用腾讯云的SCF+API服务实现简单的后端接口,并提供了一个Python出题器的实例演示。

相关服务介绍:

云函数(Serverless Cloud Function,SCF)是腾讯云为企业和开发者们提供的无服务器执行环境,帮助您在无需购买和管理服务器的情况下运行代码。 API 网关(API Gateway)是 API 托管服务,提供 API 的完整生命周期管理,包括创建、维护、发布、运行、下线等。

前几天为我家小盆友用Python写了个简单的自动数学题出题器,小家伙十分好奇,隔三差五的就要来让我演示一番😏。只是每次都要拿本出来输命令给他看实在有些麻烦,于是想着能不能加个前端页面调用,直接打开页面就能看到运行效果。

作为一个行动派派,我目标锁定了用SCF+API的方式,也就是现在很🔥的serveless方案。最大的好处当然是不用再伺候服务器了,少了很多搭建的麻烦。而且这个按实际使用量计费,对于小网站再适合不过了。

下面介绍下要怎么实现了。首先,你要有个腾讯云账号,然后参考👇的简单步骤:

  1. 创建云函数SCF。
  2. 创建API gateway,后台指定调用步骤1建好的云函数。
  3. API gateway中新建密钥,使用计划,实现访问控制并发布。
  4. 写前端页面,调用刚写好的API。
  5. 测试,解决各种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://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= $.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,测试通过后就大功告成了!给出演示地址:演示,还加上了打印功能,不用再复制粘贴了😀

演示效果

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 52 个有用的机器学习与预测API

    随着基于人工智能与机器学习的应用如雨后春笋般不断涌现,我们也看到有很多提供类似功能的 API 悄悄登上了舞台。 API 是用于构建软件应用的程序、协议以及工具的...

    机器学习AI算法工程
  • 如何最小化云API升级造成的中断?

    云提供商升级API时,开发者必须升级并重新测试自己的软件,如何为这个过程做好准备并且最小化影响? 云提供商为了扩展和改善服务进行了服务升级,通常需要进行API升...

    静一
  • 在繁杂的业务需求中,如何找到API设计的平衡点

    关于API设计,有什么好的设计方法,或者说如何来构建一个相对健壮的后端API设计体系?我觉得还是在不断的实践中犯低级错误逐步积累起来的,或者是到了不得不改的...

    jeanron100
  • 安卓9.0将限制应用程序访问,Android SDK中未记录的API

    日前,一位来自XDA的开发者表示,其在AOSP(安卓开放源代码项目)中最近的一个提交报告中发现,谷歌可能会在安卓9.0中采用更加严格的API访问权限,限制应用程...

    BestSDK
  • Oracle 19c给我的启示:RESTful API

    最近Oracle发布了19c,而且随着Openworld的到来,官网也提前做了更新,打开Oracle官网,让我一脸懵逼,鼠标不知道该往哪儿点。

    jeanron100
  • 如何支撑微服务架构落地

    编辑IT大咖说 阅读字数: 2265 用时: 7分钟 ? ? 摘要 如今微服务如日中天,优势和弊端也有各种描述,那么我们是否应该采用微服务架构?如何规避微服务的...

    IT大咖说
  • 牛津大学研究团队发文,称常温保存系统更利于肝脏移植 | 黑科技

    镁客网
  • 什么是DAO模式?

    DAO(Data Access Object)顾名思义是一个为数据库或其他持久化机制提供了抽象接口的对象,在不暴露底层持久化方案实现细节的前提下提供了各种数据访...

    唐怀瑟
  • #凯哥讲数据中台#深度剖析数据中台提供的数据服务

    业界常用的数据服务包括五种类型,Data API,Event Hub,Database,File,Terminal & APP。

    凯哥
  • Observablehq 美国 COVID-19 每日检测数曲线

    本线状图用于显示每天美国 COVID-19 的每天测试量的线状图曲线我们使用的是在线 JSON 数据,数据是通过 AWS 进行读取的。

    HoneyMoose

扫码关注云+社区

领取腾讯云代金券