Ext提交表单,返回结果中增加了"<pre></pre>"标记

问题如上.

需要在后台输出JSON的方法中加入contentType=text/html.

注意的是:

加入这句是不起作用的:response.setContentType("text/html;character=utf-8;");

要分成两步执行:

response.setCharacterEncoding("utf-8");

response.setContentType("text/html");

这样就解决了.

STRUTS默认输出是text/json的格式.在火狐上会自动上入<pre>XXXXX</pre>的字符.

实验环境:centos7虚拟机环境 我有4个html文件,文件中可能包含图片等内容,前端文件如下 . ├── About.html ├── Contact.html ├── css │ ├── reset.css │ ├── style.css │ └── style_mobile.css ├── data │ └── contact.json ├── images │ ├── About_baby.png │ ├── About_ball.png │ ├── About_be.png │ ├── About_bird.png │ ├── About_content.png │ ├── About_message.png │ ├── About_@.png │ ├── body.png │ ├── footer_baby.png │ ├── footer_ball.png │ ├── footer_be.png │ ├── footer_bird.png │ ├── footer_message.png │ ├── footer_@.png │ ├── footer.png │ ├── header.png │ └── Thumbs.db ├── img │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ ├── 5.jpg │ ├── 6.jpg │ └── Thumbs.db ├── Index.html ├── js │ ├── action.js │ └── jquery-1.9.1.min.js ├── test.html ├── webserv_linux ├── webserv_linux.c └── Work.html 请使用多进程的方式实现一个简单的web server(端口80),使得我能够在浏览器实现对各个html网页的访问。 浏览器兼容要求:Firefox,chrome、ie8+ Web server需完成get post等基础请求处理(必修) 使用makefile构建(必修) 我想利用多进程实现server客户端,代码如下,帮我检查修改main函数 #define _XOPEN_SOURCE // 消除sigaction相关报错 #include <stdio.h> // 标准输入输出 #include <stdlib.h> // 标准库函数 #include <string.h> // 字符串处理 #include <unistd.h> // UNIX标准函数 #include <sys/socket.h> // 套接字接口 #include <netinet/in.h> // 网络地址结构 #include <arpa/inet.h> // 地址转换函数 #include <sys/epoll.h> // epoll I/O多路复用 #include <fcntl.h> // 文件控制 #include <sys/stat.h> // 文件状态 #include <sys/sendfile.h> // 高效文件传输 #include <sys/types.h> // 系统类型 #include <dirent.h> // 目录操作 #include <errno.h> // 错误码 #include <sys/wait.h> // 关闭子进程 #include <signal.h> // 信号处理 #define PORT 80 // 监听端口 #define MAX_EVENTS 1024 // epoll最大事件数 #define BUFFER_SIZE 4096 // 请求缓冲区大小 #define ROOT_DIR “./web/” // Web根目录 typedef struct { int fd; char buffer[BUFFER_SIZE]; int buffer_len; int status; } client_data; /* 信号处理函数,用于销毁子进程 */ void read_childproc(int sig) { pid_t pid; int status; pid = waitpid(-1,&status,WNOHANG); if(WIFEIXITED(&status)) { printf(“normal removed proc id: %d\n”,pid); } else { printf(“abnormal removed proc id: %d\n”,pid); } } /** 根据文件扩展名获取MIME类型 @param path 文件路径 @return 对应的MIME类型字符串 */ const char *get_mime_type(const char *path) { const char *ext = strrchr(path, ‘.’); // 查找最后一个点号 if (!ext) return “text/plain”; // 无扩展名默认纯文本 // 常见文件类型匹配 if (strcmp(ext, “.html”) == 0) return “text/html”; if (strcmp(ext, “.htm”) == 0) return “text/html”; if (strcmp(ext, “.css”) == 0) return “text/css”; if (strcmp(ext, “.js”) == 0) return “application/javascript”; if (strcmp(ext, “.jpg”) == 0) return “image/jpeg”; if (strcmp(ext, “.jpeg”) == 0) return “image/jpeg”; if (strcmp(ext, “.png”) == 0) return “image/png”; if (strcmp(ext, “.gif”) == 0) return “image/gif”; if (strcmp(ext, “.json”) == 0) return “application/json”; if (strcmp(ext, “.ico”) == 0) return “image/x-icon”; return “text/plain”; // 未知扩展名默认纯文本 } /** 发送HTTP响应 @param fd 客户端套接字 @param status HTTP状态码 @param status_msg 状态描述 @param content_type 内容类型 @param body 响应体内容 @param body_len 响应体长度 */ void send_response(int fd, int status, const char *status_msg, const char *content_type, const char *body, int body_len) { char header[BUFFER_SIZE]; // 构建HTTP响应头 int header_len = snprintf(header, BUFFER_SIZE, “HTTP/1.1 %d %s\r\n” // 状态行 “Content-Type: %s\r\n” // 内容类型 “Content-Length: %d\r\n” // 内容长度 “Connection: close\r\n” // 关闭连接 “\r\n”, // 空行结束头部 status, status_msg, content_type, body_len); // 发送响应头 write(fd, header, header_len); // 发送响应体(如果有) if (body && body_len > 0) { write(fd, body, body_len); } } /** 发送文件内容 @param fd 客户端套接字 @param path 文件路径 */ void send_file(int fd, const char *path) { struct stat file_stat; // 获取文件状态信息 if (stat(path, &file_stat) < 0 || !S_ISREG(file_stat.st_mode)) { // 文件不存在或不是普通文件 send_response(fd, 404, “Not Found”, “text/html”, “ 404 Not Found”, 22); return; } // 打开文件 int file_fd = open(path, O_RDONLY); if (file_fd < 0) { // 文件打开失败 send_response(fd, 500, “Internal Server Error”, “text/html”, “ 500 Internal Error”, 26); return; } // 获取MIME类型 const char *mime_type = get_mime_type(path); fprintf(stdout, “mime_type:\n%s\n”, mime_type); char header[BUFFER_SIZE]; // 构建成功响应头 int header_len = snprintf(header, BUFFER_SIZE, “HTTP/1.1 200 OK\r\n” “Content-Type: %s\r\n” “Content-Length: %ld\r\n” “Connection: close\r\n” “\r\n”, mime_type, file_stat.st_size); // 发送响应头 write(fd, header, header_len); // 使用sendfile零拷贝发送文件内容 sendfile(fd, file_fd, NULL, file_stat.st_size); // 关闭文件 close(file_fd); } /** 处理GET请求 @param fd 客户端套接字 @param path 请求路径 */ void handle_get_request(int fd, const char *path) { char full_path[BUFFER_SIZE]; // 构建完整文件路径 snprintf(full_path, BUFFER_SIZE, “%s%s”, ROOT_DIR, path); // 路径安全检测(防止路径遍历攻击) if (strstr(path, “…/”) || strstr(path, “…\”)) { send_response(fd, 403, “Forbidden”, “text/html”, “ 403 Forbidden”, 22); return; } // 处理目录请求(以’/'结尾) if (path[strlen(path) - 1] == ‘/’) { DIR *dir = opendir(full_path); if (!dir) { // 目录打开失败 send_response(fd, 404, “Not Found”, “text/html”, “ 404 Not Found”, 22); return; } // 生成目录列表HTML char body[BUFFER_SIZE * 2] = "<html><head><title>Index of "; strcat(body, path); strcat(body, "</title></head><body><h1>Index of "); strcat(body, path); strcat(body, "</h1><hr><ul>"); struct dirent *entry; // 遍历目录项 while ((entry = readdir(dir)) != NULL) { // 跳过.和.. if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) continue; char li[256]; // 构建列表项 snprintf(li, sizeof(li), "<li><a href=\"%s%s\">%s</a></li>", path, entry->d_name, entry->d_name); strcat(body, li); } strcat(body, "</ul><hr></body></html>"); // 发送目录列表 send_response(fd, 200, "OK", "text/html", body, strlen(body)); closedir(dir); return; } // 发送文件内容 send_file(fd, full_path); } /** 处理POST请求 @param fd 客户端套接字 @param path 请求路径 @param body 请求体内容 @param body_len 请求体长度 */ void handle_post_request(int fd, const char *path, const char *body, int body_len) { // 示例:处理联系表单提交 if (strcmp(path, “/Contact.html”) == 0) { // 在实际应用中应验证和存储数据 printf(“Received form data: %.*s\n”, body_len, body); // 返回成功响应 send_response(fd, 200, “OK”, “text/html”, “ Thank You! Form submitted successfully ”, 60); } else { // 不支持其他POST路径 send_response(fd, 404, “Not Found”, “text/html”, “ 404 Not Found”, 22); } } /** 处理HTTP请求 @param fd 客户端套接字 @param request 请求数据 */ void handle_request(int fd, const char *request) { char method[16], path[256], protocol[16]; // 解析请求行 sscanf(request, “%s %s %s”, method, path, protocol); // fprintf(stdout,“%s\n%s\n %s\n”,method, path, protocol); // 处理根路径请求 if (strcmp(path, “/”) == 0) { strcpy(path, “/Index.html”); // 默认返回主页 } // 查找请求体起始位置 const char *body = strstr(request, “\r\n\r\n”); if (body) body += 4; // 跳过空行 // 方法分发 if (strcmp(method, “GET”) == 0) { handle_get_request(fd, path); } else if (strcmp(method, “POST”) == 0) { handle_post_request(fd, path, body, (body ? strlen(body) : 0)); } else { // 不支持的方法 send_response(fd, 501, “Not Implemented”, “text/html”, “ 501 Not Implemented”, 25); } } /** 主函数:设置服务器并运行事件循环 */ int main() { int server_fd; struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); pid_t pid; struct sigaction act; act.sa_handler = read_childproc; sigemptyset(&act.sa_mask); act.sa_flags = 0; int state = sigaction(SIGCHLD,&act,0); // if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { } memset(&server_fd,0,addrlen); addr.sin_family = AF_INET; addr.sin_addr.s_addr = INADDR_ANY; addr.sin_port = htons(PORT); // 设置套接字选项(允许地址重用) int opt = 1; setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); // 绑定套接字 if ((bind(server_fd, (struct sockaddr *)&addr, addrlen)) < 0) { } // 4. 开始监听 if((listen(server_fd,SOMAXCONN)) < 0) { } printf(“Web server running on port %d…\n”, PORT); printf(“Root directory: %s\n”, ROOT_DIR); // 7. 分配客户端数据存储空间 client_data *client = calloc(1, sizeof(client_data)); // while (1) { int client_fd = accept(server_fd,(struct sockaddr *) &addr,addrlen); if(client_fd < 0) { perror(“accept”); continue; } else { printf(“New connection: %s:%d\n”, inet_ntoa(addr.sin_addr),ntohs(addr.sin_port)); } pid = fork(); if(pid < 0) { close(client_fd); continue; } if(0 == pid) // child process { // 读取客户端数据 int bytes_read = read(client_fd, client->buffer + client->buffer_len, BUFFER_SIZE - client->buffer_len); if(bytes_read <=0 ) { close(client_fd); continue; } // 更新缓冲区 client->buffer_len += bytes_read; client->buffer[client->buffer_len] = '\0'; if(strstr(client->buffer, "\r\n\r\n") != NULL) { // 处理请求 handle_request(client_fd,client->buffer); // 重置缓冲区 client->buffer_len = 0; memset(client->buffer, 0, BUFFER_SIZE); } } else // father process { close(client_fd); } } close(server_fd); return 0; }
最新发布
08-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值