有人可以向我解释一下如何将 JQuery AJAX 与 C CGI 结合使用吗?
我将如何初始化 header ?
这是我的 js 代码片段:
$.ajax({
type: "post",
url: "check_username.cgi",
data: username,
function(exists){
if(exists) $("#username").after("<p>Username" + username + "is not available.</p>");
}
});
这是我的 C 代码中已成功编译的代码片段:
printf("Content-type:text/html; charset=UTF-8\n\n"); \\I am having problem with this line.
int size, exists;
int length = (int) atoi(getenv("CONTENT_LENGTH"));
char username[length], query[128] = "select username from users where username = ";
fgets(username, length, stdin);
MYSQL *conn = mysql_init(NULL);
mysql_real_connect(conn, server, user, password, database, 0, NULL, 0);
strcat(query, username);
strcat(query, ";");
exists = (int) mysql_num_rows((MYSQL_RES *)mysql_query(conn, query));
mysql_close(conn);
if(exists) return 1;
else return 0;
如果您只想告诉我使用 python 或 perl,请不要回答。
最佳答案
对于网络编程来说,C 是一种极其尴尬的语言。
正如您所要求的,我不会告诉您使用其他语言,但我会告诉您 C 是一个非常糟糕的选择 - 特别是如果您尝试仅使用标准库 - 您应该重新考虑这一点选择。在 C 应用程序中引入安全漏洞非常容易,事实上,您提供的简短代码示例中有几个相当严重的漏洞,而这些漏洞在其他语言中可以轻松避免。
printf("Content-type:text/html; charset=UTF-8\n\n");
text/html
的内容类型不适合 JSON 输出。使用application/json
。 (这不是安全问题,但值得注意。)
在这里一次打印所有 header 也会使您以后无法从脚本返回 HTTP 错误。通常最好推迟 header ,直到您的响应准备就绪。
int length = (int) atoi(getenv("CONTENT_LENGTH"));
char username[length];
您假设查询将具有 CONTENT_LENGTH
header 。可能不会。切勿对 HTTP header 的存在或有效性做出假设。
您还假设 CONTENT_LENGTH
header 的值是在堆栈上分配的合理长度。可能不是。
避免在堆栈上分配可变长度数据。虽然它是一个方便的扩展,但它很容易出错。
fgets(username, length, stdin);
您假设脚本将始终接收标准输入上的 POST
数据。不是这种情况。对脚本的 GET
或 HEAD
请求将没有内容。 (还记得我之前所说的假设吗?)
您还假设脚本的输入将是用户名
的值。它不是。它可能采用 application/x-www-form-urlencoded
格式 (foo=abc&bar=def
) 或 multipart/form-data
格式(更复杂,多行)。您不一定需要在这里处理两者,但您至少需要检查输入是否采用您期望的格式,如果是,则适本地解析它,如果不是,则返回错误。
char query[128] = "select username from users where username = ";
…
strcat(query, username);
strcat(query, ";");
您没有引用用户名
。这会使查询失败,因为大多数用户名在此处的 SQL 查询中作为文字无效。
不仅如此,您还将用户输入连接到 SQL 查询,而不执行任何形式的转义。 这会使您的应用程序容易受到 SQL 注入(inject)的攻击。</strong>用户名
中的 SQL 元字符将被解释为查询的一部分。您必须先转义 username
的值,然后再将其包含在查询中,或者(理想情况下)使用参数化查询来完全避免此问题。
更糟糕的是,您将用户输入连接到固定大小的缓冲区,而不进行任何长度检查。 这会使您的应用程序容易受到缓冲区溢出的影响。用户名过长可能会允许攻击者在您的应用程序上下文中执行任意代码。不要在 Web 应用程序中使用非长度检查的库函数,例如 strcat()
。
if(exists) return 1;
else return 0;
最后但并非最不重要的一点是:CGI 脚本的返回值是没有意义的。如果要将结果发送到 Web 浏览器,则需要以浏览器期望的格式打印它。 (在本例中为 JSON。)
关于javascript - JQuery AJAX + C CGI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40059895/