{"id":15353,"date":"2025-03-14T08:22:01","date_gmt":"2025-03-14T00:22:01","guid":{"rendered":"https:\/\/fgchen.com\/wpedu\/?p=15353"},"modified":"2026-03-30T14:28:35","modified_gmt":"2026-03-30T06:28:35","slug":"%e6%95%99%e6%a1%88%ef%bc%9acrud-%e6%87%89%e7%94%a8-app%ef%bc%88%e7%8f%ad%e7%b4%9a%e7%95%99%e8%a8%80%e6%9d%bf%e8%88%87%e8%81%8a%e5%a4%a9%e5%ae%a4%ef%bc%89","status":"publish","type":"post","link":"https:\/\/fgchen.com\/wpedu\/2025\/03\/%e6%95%99%e6%a1%88%ef%bc%9acrud-%e6%87%89%e7%94%a8-app%ef%bc%88%e7%8f%ad%e7%b4%9a%e7%95%99%e8%a8%80%e6%9d%bf%e8%88%87%e8%81%8a%e5%a4%a9%e5%ae%a4%ef%bc%89\/","title":{"rendered":"\u6559\u6848\uff1aCRUD \u61c9\u7528 App\uff08\u73ed\u7d1a\u7559\u8a00\u677f\u8207\u804a\u5929\u5ba4\uff09"},"content":{"rendered":"\n<p>\u9019\u500b\u6559\u6848\u5c07\u57fa\u65bc <strong>Node.js<\/strong> \u4f5c\u70ba\u5f8c\u7aef\uff0c\u642d\u914d <strong>Express.js<\/strong> \u4f5c\u70ba Web \u6846\u67b6\uff0c\u4e26\u4f7f\u7528 <strong>MongoDB\uff08Mongoose\uff09<\/strong> \u4f5c\u70ba\u8cc7\u6599\u5eab\uff0c\u56e0\u70ba\u5b83\u6613\u65bc\u4f7f\u7528\uff0c\u9069\u5408 CRUD \u61c9\u7528\uff0c\u4e14\u8207 JavaScript \u517c\u5bb9\u6027\u9ad8\u3002\u524d\u7aef\u5247\u4f7f\u7528 <strong>HTML\u3001CSS\u3001JavaScript\uff08Fetch API \u6216\u7c21\u55ae\u7684 Vue.js\uff09<\/strong> \u4f86\u5be6\u4f5c\u73ed\u7d1a\u7559\u8a00\u677f\u8207\u804a\u5929\u5ba4\u3002<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>\u8ab2\u7a0b\u76ee\u6a19<\/strong><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>\u4e86\u89e3 <strong>CRUD\uff08Create, Read, Update, Delete\uff09<\/strong> \u7684\u6982\u5ff5\u8207\u5be6\u4f5c\u65b9\u5f0f\u3002<\/li>\n\n\n\n<li>\u5b78\u7fd2 <strong>Node.js + Express.js<\/strong> \u642d\u5efa\u5f8c\u7aef API\u3002<\/li>\n\n\n\n<li>\u719f\u6089 <strong>MongoDB\uff08Mongoose\uff09<\/strong> \u9032\u884c\u8cc7\u6599\u5b58\u53d6\u3002<\/li>\n\n\n\n<li>\u524d\u7aef\u900f\u904e <strong>Fetch API \/ Vue.js<\/strong> \u9032\u884c API \u547c\u53eb\u8207\u52d5\u614b\u6e32\u67d3\u3002<\/li>\n\n\n\n<li>\u900f\u904e <strong>WebSocket\uff08Socket.io\uff09<\/strong> \u5be6\u73fe\u5373\u6642\u804a\u5929\u5ba4\u529f\u80fd\u3002<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>\u9069\u7528\u5c0d\u8c61<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>\u5927\u5b78\u5165\u9580\u7d1a\u5b78\u751f\uff0c\u6709\u57fa\u672c <strong>JavaScript\u3001HTML\u3001CSS<\/strong> \u57fa\u790e\u3002<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>\u8ab2\u7a0b\u6642\u9593\u898f\u5283\uff089 \u9031\uff09<\/strong><\/h3>\n\n\n\n<p>\u6bcf\u500b\u8b70\u984c\u7d04 <strong>3 \u9031<\/strong>\uff0c\u5171 <strong>9 \u9031<\/strong> \u5b8c\u6210\u5c08\u6848\u3002<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>\u9031\u6b21<\/th><th>\u5167\u5bb9<\/th><th>\u4e3b\u8981\u6280\u8853<\/th><\/tr><\/thead><tbody><tr><td>1-3<\/td><td>CRUD API \u958b\u767c\uff08\u7559\u8a00\u677f\uff09<\/td><td>Node.js, Express.js, MongoDB (Mongoose)<\/td><\/tr><tr><td>4-6<\/td><td>\u524d\u7aef\u4ecb\u9762\u958b\u767c\u8207 API \u4e32\u63a5<\/td><td>HTML, CSS, JavaScript\uff08Fetch API \/ Vue.js\uff09<\/td><\/tr><tr><td>7-9<\/td><td>\u5373\u6642\u804a\u5929\u5ba4\u529f\u80fd\uff08WebSocket\uff09<\/td><td>Socket.io, WebSocket<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u7b2c\u4e00\u90e8\u5206\uff1a\u7559\u8a00\u677f CRUD<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>1.1 \u5f8c\u7aef API \u958b\u767c<\/strong><\/h3>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>\u5b89\u88dd\u8207\u5c08\u6848\u521d\u59cb\u5316<\/strong><\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">mkdir class-board\ncd class-board\nnpm init -y\nnpm install express mongoose cors body-parser dotenv\n<\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Express.js<\/strong>\uff1a\u8655\u7406 API \u8def\u7531<\/li>\n\n\n\n<li><strong>Mongoose<\/strong>\uff1a\u64cd\u4f5c MongoDB<\/li>\n\n\n\n<li><strong>CORS<\/strong>\uff1a\u89e3\u6c7a\u8de8\u57df\u8acb\u6c42<\/li>\n\n\n\n<li><strong>body-parser<\/strong>\uff1a\u89e3\u6790 JSON<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>\u5efa\u7acb <code>server.js<\/code><\/strong><\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">require('dotenv').config();\nconst express = require('express');\nconst mongoose = require('mongoose');\nconst cors = require('cors');\n\nconst app = express();\napp.use(cors());\napp.use(express.json());\n\nmongoose.connect(process.env.MONGO_URL, {\n    useNewUrlParser: true,\n    useUnifiedTopology: true,\n}).then(() => console.log(\"MongoDB Connected\"));\n\nconst messageSchema = new mongoose.Schema({\n    user: String,\n    message: String,\n    createdAt: { type: Date, default: Date.now }\n});\n\nconst Message = mongoose.model('Message', messageSchema);\n\n\/\/ \u5efa\u7acb\u7559\u8a00\napp.post('\/messages', async (req, res) => {\n    const newMessage = new Message(req.body);\n    await newMessage.save();\n    res.json(newMessage);\n});\n\n\/\/ \u8b80\u53d6\u7559\u8a00\napp.get('\/messages', async (req, res) => {\n    const messages = await Message.find().sort({ createdAt: -1 });\n    res.json(messages);\n});\n\n\/\/ \u66f4\u65b0\u7559\u8a00\napp.put('\/messages\/:id', async (req, res) => {\n    const updatedMessage = await Message.findByIdAndUpdate(req.params.id, req.body, { new: true });\n    res.json(updatedMessage);\n});\n\n\/\/ \u522a\u9664\u7559\u8a00\napp.delete('\/messages\/:id', async (req, res) => {\n    await Message.findByIdAndDelete(req.params.id);\n    res.json({ message: \"Deleted\" });\n});\n\napp.listen(3000, () => console.log('Server running on port 3000'));\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\"><strong>\u74b0\u5883\u8b8a\u6578 <code>.env<\/code><\/strong><\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">MONGO_URL=mongodb+srv:\/\/your_user:your_password@cluster0.mongodb.net\/myDatabase\n<\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u7b2c\u4e8c\u90e8\u5206\uff1a\u524d\u7aef\u7559\u8a00\u677f\u4ecb\u9762<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>2.1 \u524d\u7aef HTML<\/strong><\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;!DOCTYPE html>\n&lt;html lang=\"zh-TW\">\n&lt;head>\n    &lt;meta charset=\"UTF-8\">\n    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    &lt;title>\u73ed\u7d1a\u7559\u8a00\u677f&lt;\/title>\n    &lt;script defer src=\"app.js\">&lt;\/script>\n&lt;\/head>\n&lt;body>\n    &lt;h1>\u73ed\u7d1a\u7559\u8a00\u677f&lt;\/h1>\n    &lt;input id=\"username\" type=\"text\" placeholder=\"\u8f38\u5165\u4f60\u7684\u540d\u5b57\">\n    &lt;textarea id=\"message\" placeholder=\"\u8f38\u5165\u7559\u8a00\">&lt;\/textarea>\n    &lt;button onclick=\"sendMessage()\">\u9001\u51fa&lt;\/button>\n\n    &lt;div id=\"messages\">&lt;\/div>\n&lt;\/body>\n&lt;\/html>\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>2.2 JavaScript (<code>app.js<\/code>)<\/strong><\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">const apiUrl = \"http:\/\/localhost:3000\/messages\";\n\nasync function loadMessages() {\n    const res = await fetch(apiUrl);\n    const messages = await res.json();\n    document.getElementById(\"messages\").innerHTML = messages.map(msg =>\n        `&lt;p>&lt;strong>${msg.user}:&lt;\/strong> ${msg.message} &lt;button onclick=\"deleteMessage('${msg._id}')\">\u522a\u9664&lt;\/button>&lt;\/p>`\n    ).join(\"\");\n}\n\nasync function sendMessage() {\n    const user = document.getElementById(\"username\").value;\n    const message = document.getElementById(\"message\").value;\n    await fetch(apiUrl, {\n        method: \"POST\",\n        headers: { \"Content-Type\": \"application\/json\" },\n        body: JSON.stringify({ user, message })\n    });\n    loadMessages();\n}\n\nasync function deleteMessage(id) {\n    await fetch(`${apiUrl}\/${id}`, { method: \"DELETE\" });\n    loadMessages();\n}\n\nloadMessages();\n<\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u7b2c\u4e09\u90e8\u5206\uff1a\u5373\u6642\u804a\u5929\u5ba4<\/strong><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>3.1 \u5b89\u88dd WebSocket<\/strong><\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">npm install socket.io\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>3.2 \u4f3a\u670d\u5668\u7aef WebSocket<\/strong><\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">const http = require('http');\nconst { Server } = require(\"socket.io\");\n\nconst server = http.createServer(app);\nconst io = new Server(server, { cors: { origin: \"*\" } });\n\nio.on('connection', (socket) => {\n    console.log(\"User connected\");\n    socket.on('chatMessage', (msg) => {\n        io.emit('chatMessage', msg);\n    });\n});\n\nserver.listen(3000, () => console.log('Server running on port 3000'));\n<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>3.3 \u524d\u7aef WebSocket (<code>chat.js<\/code>)<\/strong><\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">const socket = io(\"http:\/\/localhost:3000\");\n\ndocument.getElementById(\"send\").addEventListener(\"click\", () => {\n    const user = document.getElementById(\"username\").value;\n    const message = document.getElementById(\"message\").value;\n    socket.emit(\"chatMessage\", `${user}: ${message}`);\n});\n\nsocket.on(\"chatMessage\", (msg) => {\n    const div = document.createElement(\"div\");\n    div.innerText = msg;\n    document.getElementById(\"chat\").appendChild(div);\n});\n<\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>\u7e3d\u7d50<\/strong><\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>\u7b2c\u4e00\u968e\u6bb5<\/strong>\uff1a\u5b8c\u6210\u57fa\u672c\u7684 CRUD \u7559\u8a00\u677f\uff0c\u719f\u6089 API \u958b\u767c\u8207 MongoDB \u64cd\u4f5c\u3002<\/li>\n\n\n\n<li><strong>\u7b2c\u4e8c\u968e\u6bb5<\/strong>\uff1a\u524d\u7aef\u4e32\u63a5 API\uff0c\u5efa\u7acb\u7559\u8a00\u677f UI\u3002<\/li>\n\n\n\n<li><strong>\u7b2c\u4e09\u968e\u6bb5<\/strong>\uff1a\u52a0\u5165 WebSocket\uff0c\u5373\u6642\u804a\u5929\u5ba4\u529f\u80fd\u3002<\/li>\n<\/ul>\n\n\n\n<p>\u9019\u500b\u6559\u6848\u5b8c\u6574\u6db5\u84cb <strong>Node.js \u5f8c\u7aef\u3001MongoDB \u8cc7\u6599\u5eab\u3001\u524d\u7aef API \u4e32\u63a5\u3001\u5373\u6642 WebSocket \u61c9\u7528<\/strong>\uff0c\u9069\u5408\u4f5c\u70ba\u5165\u9580\u5be6\u4f5c\u5c08\u6848\uff01\ud83d\ude80<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u9019\u500b\u6559\u6848\u5c07\u57fa\u65bc Node.js \u4f5c\u70ba\u5f8c\u7aef\uff0c\u642d\u914d Express.js \u4f5c\u70ba We &hellip; <\/p>\n","protected":false},"author":1,"featured_media":14942,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","fifu_image_url":"","fifu_image_alt":"","footnotes":""},"categories":[266],"tags":[],"class_list":["post-15353","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-266"],"_links":{"self":[{"href":"https:\/\/fgchen.com\/wpedu\/wp-json\/wp\/v2\/posts\/15353","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fgchen.com\/wpedu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fgchen.com\/wpedu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fgchen.com\/wpedu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fgchen.com\/wpedu\/wp-json\/wp\/v2\/comments?post=15353"}],"version-history":[{"count":1,"href":"https:\/\/fgchen.com\/wpedu\/wp-json\/wp\/v2\/posts\/15353\/revisions"}],"predecessor-version":[{"id":15354,"href":"https:\/\/fgchen.com\/wpedu\/wp-json\/wp\/v2\/posts\/15353\/revisions\/15354"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/fgchen.com\/wpedu\/wp-json\/wp\/v2\/media\/14942"}],"wp:attachment":[{"href":"https:\/\/fgchen.com\/wpedu\/wp-json\/wp\/v2\/media?parent=15353"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fgchen.com\/wpedu\/wp-json\/wp\/v2\/categories?post=15353"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fgchen.com\/wpedu\/wp-json\/wp\/v2\/tags?post=15353"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}