目录
- 1. 基础准备
- 必备工具:
- 2. 目录结构
- 3. 用户登录(使用简单的文件系统管理)
- 4. 富文本编辑器和展示
- 5. 样式文件
- 6. 配置 Web 服务器
- 7. 运行和测试
构建一个简单的 Web 站点实现富文本写入和展示、用户登录以及文本目录划分需要结合多个技术,包括 C 语言的 CGI(Common Gateway Interface)、HTML、JavaScript 和 CSS 以及一个简单的文件系统管理。下面是一个基本的实现步骤和示例代码。
1. 基础准备
必备工具:
- 一个 Web 服务器(例如 Apache 或 Nginx)支持 CGI。
- HTML、CSS 和 JavaScript 基础知识。
- C 语言编译器(例如
gcc
)。
2. 目录结构
/var/www/cgi-bin/ # 放置 CGI 脚本
/var/www/html/ # 放置 HTML 文件
/var/www/html/css/ # 放置 CSS 文件
/var/www/html/js/ # 放置 JavaScript 文件
3. 用户登录(使用简单的文件系统管理)
login.html(放在 /var/www/html/
中):
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>User Login</title><link rel="stylesheet" href="css/style.css">
</head>
<body><form action="/cgi-bin/login.cgi" method="post"><label for="username">Username:</label><input type="text" id="username" name="username" required><label for="password">Password:</label><input type="password" id="password" name="password" required><button type="submit">Login</button></form>
</body>
</html>
login.cgi(放在 /var/www/cgi-bin/
中):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>void get_post_data(char *data) {char *lenstr;long len;lenstr = getenv("CONTENT_LENGTH");if(lenstr == NULL || sscanf(lenstr,"%ld",&len)!=1 || len>1024) {printf("Content-type:text/html\n\n");printf("<html><body>Invalid POST data</body></html>");exit(1);}fgets(data, len+1, stdin);
}int main() {char data[1024];char username[100], password[100];get_post_data(data);sscanf(data, "username=%99[^&]&password=%99s", username, password);// 简单的用户名密码验证 (应替换为更安全的方法)if(strcmp(username, "admin") == 0 && strcmp(password, "password") == 0) {printf("Content-type:text/html\n\n");printf("<html><body>Login successful!<br><a href=\"editor.html\">Go to Editor</a></body></html>");} else {printf("Content-type:text/html\n\n");printf("<html><body>Invalid credentials. <a href=\"/login.html\">Try again</a></body></html>");}return 0;
}
4. 富文本编辑器和展示
editor.html(放在 /var/www/html/
中):
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Rich Text Editor</title><link rel="stylesheet" href="css/style.css"><script src="js/editor.js"></script>
</head>
<body><form action="/cgi-bin/save_text.cgi" method="post"><textarea id="editor" name="editor" rows="10" cols="80"></textarea><button type="submit">Save</button></form><div><h2>Text Directory</h2><ul id="directory"></ul></div>
</body>
</html>
editor.js(放在 /var/www/html/js/
中):
document.addEventListener("DOMContentLoaded", function() {const directory = document.getElementById('directory');// Fetch directory contentsfetch('/cgi-bin/list_texts.cgi').then(response => response.json()).then(data => {data.forEach(file => {let li = document.createElement('li');let a = document.createElement('a');a.href = `/cgi-bin/display_text.cgi?file=${file}`;a.innerText = file;li.appendChild(a);directory.appendChild(li);});});
});
save_text.cgi(放在 /var/www/cgi-bin/
中):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>void get_post_data(char *data) {char *lenstr;long len;lenstr = getenv("CONTENT_LENGTH");if(lenstr == NULL || sscanf(lenstr,"%ld",&len)!=1 || len>8192) {printf("Content-type:text/html\n\n");printf("<html><body>Invalid POST data</body></html>");exit(1);}fgets(data, len+1, stdin);
}void save_to_file(const char *filename, const char *data) {FILE *file = fopen(filename, "w");if(file == NULL) {printf("Content-type:text/html\n\n");printf("<html><body>Could not save file.</body></html>");exit(1);}fprintf(file, "%s", data);fclose(file);
}int main() {char data[8192];get_post_data(data);// Saving the data to a file (simple naming, should be more secure)save_to_file("/var/www/texts/saved_text.html", data);printf("Content-type:text/html\n\n");printf("<html><body>Text saved! <a href=\"editor.html\">Back to Editor</a></body></html>");return 0;
}
list_texts.cgi(放在 /var/www/cgi-bin/
中):
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>int main() {DIR *d;struct dirent *dir;char result[8192] = "[";d = opendir("/var/www/texts/");if(d) {while((dir = readdir(d)) != NULL) {if(dir->d_type == DT_REG) {strcat(result, "\"");strcat(result, dir->d_name);strcat(result, "\",");}}closedir(d);if(result[strlen(result) - 1] == ',') {result[strlen(result) - 1] = '\0';}}strcat(result, "]");printf("Content-type: application/json\n\n");printf("%s", result);return 0;
}
display_text.cgi(放在 /var/www/cgi-bin/
中):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>void display_file(const char *filename) {FILE *file = fopen(filename, "r");if(file == NULL) {printf("Content-type:text/html\n\n");printf("<html><body>Could not open file.</body></html>");exit(1);}printf("Content-type:text/html\n\n");printf("<html><body>");char ch;while((ch = fgetc(file)) != EOF) {putchar(ch);}printf("</body></html>");fclose(file);
}int main(int argc, char *argv[]) {char *query_string = getenv("QUERY_STRING");char filename[256];if(query_string == NULL || sscanf(query_string, "file=%255s", filename) != 1) {printf("Content-type:text/html\n\n");printf("<html><body>Invalid file request.</body></html>");exit(1);}char filepath[512];snprintf(filepath, sizeof(filepath), "/var/www/texts/%s", filename);display_file(filepath);return 0;
}
5. 样式文件
style.css(放在 /var/www/html/css/
中):
body {font-family: Arial, sans-serif;margin: 20px;
}form {margin-bottom: 20px;
}textarea {width: 100%;height: 200px;
}button {padding: 10px 20px;background-color: #4CAF50;color: white;border: none;cursor: pointer;
}button:hover {background-color: #45a049;
}
6. 配置 Web 服务器
确保你的 Web 服务器配置正确,并支持 CGI 脚本。例如,如果你使用 Apache,确保 httpd.conf
中有如下配置:
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
<Directory "/var/www/cgi-bin">AllowOverride NoneOptions +ExecCGIAddHandler cgi-script .cgi .pl .pyRequire all granted
</Directory>
7. 运行和测试
- 将所有文件放在对应的目录中。
- 访问
http://yourserver/login.html
进行用户登录。 - 成功登录后,访问富文本编辑器进行内容输入和保存。
- 确保你有 `/var/www
/texts/` 目录用来保存文本文件,并具有写权限。
这只是一个基础的示例,实际应用中需要考虑更多安全性和功能性方面的细节。