我正在尝试在公共(public)网页中为 AWS RDS MySQL 数据库实现 SQL 查询接口(interface)。理想情况下,用户将在搜索字段中输入 SQL 查询,按下“查询”按钮,API 网关请求将触发 Lambda 函数,从数据库中提取、返回并打印到网页上的相关数据。
到目前为止,我有以下 Lambda 函数(我能够成功测试):
const AWS = require('aws-sdk')
const RDS = new AWS.RDSDataService()
exports.handler = async (event, context) => {
console.log(JSON.stringify(event, null, 2)) // Log the entire event passed in
// Get the sqlStatement string value
// TODO: Implement a more secure way (e.g. "escaping") the string to avoid SQL injection
var sqlStatement = event.sqlStatement;
// The Lambda environment variables for the Aurora Cluster Arn, Database Name, and the AWS Secrets Arn hosting the master credentials of the serverless db
var DBSecretsStoreArn = process.env.DBSecretsStoreArn;
var DBAuroraClusterArn = process.env.DBAuroraClusterArn;
var DatabaseName = process.env.DatabaseName;
const params = {
awsSecretStoreArn: DBSecretsStoreArn,
dbClusterOrInstanceArn: DBAuroraClusterArn,
sqlStatements: sqlStatement,
database: DatabaseName
}
try {
let dbResponse = await RDS.executeSql(params).promise()
console.log(JSON.stringify(dbResponse, null, 2))
var json_response = JSON.stringify(dbResponse)
return json_response
} catch (error) {
console.log(error)
return error
}
}
当使用以下测试格式进行测试时,我认为该函数返回一个 JSON blob。
测试事件格式:
{
"sqlStatement": "SELECT * FROM Table WHERE Name='JOHN DOE'"
}
测试事件结果:
..., {\"stringValue\":\"JOHN DOE\"},{\"stringValue\":\"2019-11-15\"},{\"stringValue\":\"AL\"},{\"stringValue\":\"1\"},{\"stringValue\":\"130\"},{\"stringValue\":\"Washington Co. Jail\"},{\"stringValue\":\"2019-10-31\"}, ...
我配置了以下 API 触发器详细信息:
API endpoint: https://****************.amazonaws.com/prod/query
API Type: rest
Authorization: NONE
Method: POST
Resource path: /query
Stage: prod
我还有以下 Lambda 角色配置策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": [
"secretsmanager:GetSecretValue",
"rds:*",
"rds-data:*"
],
"Resource": "*"
}
]
}
同时,该 API 具有以下方法/配置:
除了此设置中的任何潜在问题(即 Lambda 和 API 触发器之间的链接以及传递/查询/返回的数据格式)之外,我需要弄清楚如何通过单击来实际调用整个过程一个查询按钮。因此,例如,用户将在页面上,在 HTML 元素中键入 SELECT * FROM Table WHERE Name="JOHN DOE",单击 HTML 按钮“Query”,然后该过程就会实现;然后,查询结果将以任何格式(简单来说,目前是一个困惑的字符串,但理想情况下最终会在引导数据表中)填充到另一个 HTML 元素中。
我当前有一个 config.js 文件,其中包含:
window._config = {
api: {
invokeUrl: 'https://******************.amazonaws.com/prod',
}
};
我还有一个 query.js 文件,其中包含基于在线零散教程的函数(可能不正确)尝试:
(function DisplayQuery($) {
var query = document.getElementById("sql-placeholder").value;
function passQuery(query) {
$.ajax({
method: 'POST',
url: _config.api.invokeUrl + '/query',
data: JSON.stringify({
sqlStatement: query
}),
contentType: 'application/json',
success: document.getElementById("text-box").innerHTML = result.value,
error: function ajaxError() {
console.error('Error requesting ride');
}
})
}
}(jQuery));
在我的index.html 文件中,我有这些搜索字段和按钮元素:
<div class="active-cyan-4 mb-4">
<input id="sql-placeholder" class="form-control" type="text" placeholder="Write SQL here..." aria-label="Search">
</div>
<div class="col-md-1">
<button type="button" class="btn btn-primary" onclick="DisplayQuery()">Query</button>
</div>
最后,这将是测试元素,一旦 RDS --> Lambda --> API Gateway 返回我的字符串格式 SQL 查询结果,就会在其中显示它们:
<div class="container-fluid">
<p class= "test-box-class" id="test-box"><i>This is a test box for database query connection</i></p>
</div>
这可能很多,但我想知道是否有人对如何运行此过程有任何见解,至少足够好,以便点击“查询”按钮可以将某些内容返回到网页。
最佳答案
按照@antonku的回答后,“缺少身份验证 token ”错误的原因是,您尝试在浏览器中访问“POST”http方法,浏览器使用“GET”http方法请求URL。
当 URL 不正确时,您也可能会收到相同的错误消息。
添加一些console.log语句以查看前端的api响应
var DisplayQuery;
(function($) {
DisplayQuery = function() {
$.ajax({
method: 'POST',
url: _config.api.invokeUrl + '/query',
data: $('#sql-placeholder').val(),
contentType: 'application/json',
success: function(response) {
console.log('response: ', response);
$('#test-box').text(JSON.stringify(response))
},
error: function ajaxError(error) {
console.error('Error requesting ride');
}
})
}
}(jQuery));
关于html - 使用 Lambda、API 网关和 HTTP 请求将 AWS RDS 的查询结果显示到公共(public)网页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59112800/