{"id":85669,"date":"2026-07-27T20:25:11","date_gmt":"2026-07-27T12:25:11","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/85669.html"},"modified":"2026-07-27T20:25:11","modified_gmt":"2026-07-27T12:25:11","slug":"%e6%99%ba%e8%b0%b1ai%e8%b0%83%e7%94%a8%ef%bc%88fetchnodejs%ef%bc%89","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/85669.html","title":{"rendered":"\u667a\u8c31AI\u8c03\u7528\uff08FETCH+NODE+JS\uff09"},"content":{"rendered":"<h2>\u4e0a\u56fe&#xff01;&#xff01;&#xff01;<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" height=\"915\" src=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/07\/20260727122510-6a674e26387fb.png\" width=\"1910\" \/><\/p>\n<h2>HTML\u6e90\u7801<\/h2>\n<p>&lt;!DOCTYPE html&gt;<br \/>\n&lt;html lang&#061;&#034;zh-CN&#034;&gt;<br \/>\n&lt;head&gt;<br \/>\n    &lt;meta charset&#061;&#034;UTF-8&#034;&gt;<br \/>\n    &lt;meta name&#061;&#034;viewport&#034; content&#061;&#034;width&#061;device-width, initial-scale&#061;1.0&#034;&gt;<br \/>\n    &lt;title&gt;\u667a\u8c31 AI \u804a\u5929\u52a9\u624b&lt;\/title&gt;<br \/>\n    &lt;!&#8211; marked.js: Markdown \u8f6c HTML&#xff08;\u56fd\u5185 CDN &#043; \u81ea\u5efa\u515c\u5e95&#xff09; &#8211;&gt;<br \/>\n    &lt;script src&#061;&#034;https:\/\/cdn.bootcdn.net\/ajax\/libs\/marked\/9.1.6\/marked.min.js&#034;&gt;&lt;\/script&gt;<br \/>\n    &lt;style&gt;<br \/>\n        * { margin: 0; padding: 0; box-sizing: border-box; }<br \/>\n        body {<br \/>\n            font-family: &#039;Microsoft YaHei&#039;, &#039;PingFang SC&#039;, sans-serif;<br \/>\n            background: #f0f4f8;<br \/>\n            height: 100vh;<br \/>\n            display: flex;<br \/>\n            justify-content: center;<br \/>\n            align-items: center;<br \/>\n        }<br \/>\n        .chat-container {<br \/>\n            width: 820px;<br \/>\n            max-width: 98vw;<br \/>\n            height: 85vh;<br \/>\n            background: #fff;<br \/>\n            border-radius: 16px;<br \/>\n            box-shadow: 0 8px 32px rgba(0,0,0,0.1);<br \/>\n            display: flex;<br \/>\n            flex-direction: column;<br \/>\n            overflow: hidden;<br \/>\n        }<br \/>\n        .chat-header {<br \/>\n            background: linear-gradient(135deg, #3b82f6, #6366f1);<br \/>\n            color: #fff;<br \/>\n            padding: 18px 24px;<br \/>\n            font-size: 18px;<br \/>\n            font-weight: 600;<br \/>\n            text-align: center;<br \/>\n            letter-spacing: 2px;<br \/>\n        }<br \/>\n        .chat-messages {<br \/>\n            flex: 1;<br \/>\n            padding: 20px;<br \/>\n            overflow-y: auto;<br \/>\n            display: flex;<br \/>\n            flex-direction: column;<br \/>\n            gap: 14px;<br \/>\n            background: #fafbfc;<br \/>\n            min-height: 0;<br \/>\n        }<br \/>\n        .chat-messages::-webkit-scrollbar { width: 6px; }<br \/>\n        .chat-messages::-webkit-scrollbar-thumb {<br \/>\n            background: #d1d5db;<br \/>\n            border-radius: 3px;<br \/>\n        }<br \/>\n        .message {<br \/>\n            max-width: 85%;<br \/>\n            padding: 12px 16px;<br \/>\n            border-radius: 12px;<br \/>\n            line-height: 1.7;<br \/>\n            animation: fadeIn 0.3s ease;<br \/>\n            overflow-x: auto;<br \/>\n            flex-shrink: 0;<br \/>\n            min-height: 0;<br \/>\n        }<br \/>\n        &#064;keyframes fadeIn {<br \/>\n            from { opacity: 0; }<br \/>\n            to { opacity: 1; }<br \/>\n        }<br \/>\n        .message.user {<br \/>\n            align-self: flex-end;<br \/>\n            background: #3b82f6;<br \/>\n            color: #fff;<br \/>\n            border-bottom-right-radius: 4px;<br \/>\n            overflow-wrap: break-word;<br \/>\n            word-break: break-word;<br \/>\n        }<br \/>\n        .message.assistant {<br \/>\n            align-self: flex-start;<br \/>\n            background: #fff;<br \/>\n            border: 1px solid #e5e7eb;<br \/>\n            border-bottom-left-radius: 4px;<br \/>\n            color: #374151;<br \/>\n            overflow-x: auto;<br \/>\n            overflow-wrap: break-word;<br \/>\n            word-break: break-word;<br \/>\n        }<br \/>\n        .message.loading {<br \/>\n            background: #f3f4f6;<br \/>\n            color: #9ca3af;<br \/>\n            font-style: italic;<br \/>\n        }<\/p>\n<p>        \/* &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; Markdown \u6e32\u67d3\u6837\u5f0f &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; *\/<\/p>\n<p>        \/* \u6bb5\u843d *\/<br \/>\n        .message.assistant p {<br \/>\n            margin-bottom: 8px;<br \/>\n        }<br \/>\n        .message.assistant p:last-child {<br \/>\n            margin-bottom: 0;<br \/>\n        }<\/p>\n<p>        \/* \u52a0\u7c97 \/ \u659c\u4f53 *\/<br \/>\n        .message.assistant strong { color: #1f2937; font-weight: 700; }<br \/>\n        .message.assistant em { color: #6b7280; }<\/p>\n<p>        \/* \u884c\u5185\u4ee3\u7801 *\/<br \/>\n        .message.assistant code {<br \/>\n            background: #f1f5f9;<br \/>\n            color: #e11d48;<br \/>\n            padding: 2px 6px;<br \/>\n            border-radius: 4px;<br \/>\n            font-size: 0.9em;<br \/>\n            font-family: &#039;Consolas&#039;, &#039;Courier New&#039;, monospace;<br \/>\n        }<\/p>\n<p>        \/* \u4ee3\u7801\u5757 *\/<br \/>\n        .message.assistant pre {<br \/>\n            background: #1e293b;<br \/>\n            color: #e2e8f0;<br \/>\n            padding: 14px 16px;<br \/>\n            border-radius: 8px;<br \/>\n            overflow-x: auto;<br \/>\n            margin: 10px 0;<br \/>\n            font-size: 13px;<br \/>\n            line-height: 1.5;<br \/>\n            position: relative;<br \/>\n        }<br \/>\n        .message.assistant pre code {<br \/>\n            background: none;<br \/>\n            color: inherit;<br \/>\n            padding: 0;<br \/>\n            font-size: inherit;<br \/>\n        }<\/p>\n<p>        \/* \u6709\u5e8f\/\u65e0\u5e8f\u5217\u8868 *\/<br \/>\n        .message.assistant ul,<br \/>\n        .message.assistant ol {<br \/>\n            padding-left: 20px;<br \/>\n            margin: 6px 0;<br \/>\n        }<br \/>\n        .message.assistant li {<br \/>\n            margin-bottom: 4px;<br \/>\n        }<\/p>\n<p>        \/* \u5f15\u7528 *\/<br \/>\n        .message.assistant blockquote {<br \/>\n            border-left: 3px solid #3b82f6;<br \/>\n            padding-left: 12px;<br \/>\n            margin: 8px 0;<br \/>\n            color: #6b7280;<br \/>\n            background: #f8fafc;<br \/>\n            border-radius: 0 4px 4px 0;<br \/>\n        }<\/p>\n<p>        \/* \u5206\u5272\u7ebf *\/<br \/>\n        .message.assistant hr {<br \/>\n            border: none;<br \/>\n            border-top: 1px solid #e5e7eb;<br \/>\n            margin: 12px 0;<br \/>\n        }<\/p>\n<p>        \/* &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; \u94fe\u63a5 &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; *\/<br \/>\n        .message.assistant a {<br \/>\n            color: #3b82f6;<br \/>\n            text-decoration: underline;<br \/>\n            word-break: break-all;<br \/>\n        }<br \/>\n        .message.assistant a:hover {<br \/>\n            color: #2563eb;<br \/>\n        }<\/p>\n<p>        \/* &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; \u8868\u683c\u6837\u5f0f&#xff08;\u91cd\u70b9&#xff09; &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; *\/<br \/>\n        .message.assistant .table-wrapper {<br \/>\n            overflow-x: auto;<br \/>\n            margin: 10px 0;<br \/>\n            border-radius: 6px;<br \/>\n            border: 1px solid #e5e7eb;<br \/>\n        }<br \/>\n        .message.assistant table {<br \/>\n            width: 100%;<br \/>\n            border-collapse: collapse;<br \/>\n            font-size: 14px;<br \/>\n            white-space: nowrap;<br \/>\n        }<br \/>\n        .message.assistant thead {<br \/>\n            background: #f1f5f9;<br \/>\n        }<br \/>\n        .message.assistant th {<br \/>\n            padding: 10px 14px;<br \/>\n            text-align: left;<br \/>\n            font-weight: 600;<br \/>\n            color: #374151;<br \/>\n            border-bottom: 2px solid #d1d5db;<br \/>\n            white-space: nowrap;<br \/>\n        }<br \/>\n        .message.assistant td {<br \/>\n            padding: 8px 14px;<br \/>\n            border-bottom: 1px solid #f1f5f9;<br \/>\n            color: #4b5563;<br \/>\n        }<br \/>\n        .message.assistant tbody tr:hover {<br \/>\n            background: #f8fafc;<br \/>\n        }<br \/>\n        .message.assistant tbody tr:last-child td {<br \/>\n            border-bottom: none;<br \/>\n        }<\/p>\n<p>        \/* &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; \u6587\u4ef6\u4fe1\u606f\u5361\u7247 &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; *\/<br \/>\n        .file-card {<br \/>\n            display: flex;<br \/>\n            align-items: center;<br \/>\n            gap: 10px;<br \/>\n            padding: 10px 14px;<br \/>\n            border: 1px solid #e5e7eb;<br \/>\n            border-radius: 8px;<br \/>\n            background: #f8fafc;<br \/>\n            margin: 6px 0;<br \/>\n            transition: background 0.2s;<br \/>\n        }<br \/>\n        .file-card:hover { background: #f1f5f9; }<br \/>\n        .file-icon {<br \/>\n            width: 36px;<br \/>\n            height: 36px;<br \/>\n            border-radius: 6px;<br \/>\n            background: #3b82f6;<br \/>\n            color: #fff;<br \/>\n            display: flex;<br \/>\n            align-items: center;<br \/>\n            justify-content: center;<br \/>\n            font-size: 14px;<br \/>\n            font-weight: 700;<br \/>\n            flex-shrink: 0;<br \/>\n        }<br \/>\n        .file-info {<br \/>\n            flex: 1;<br \/>\n            min-width: 0;<br \/>\n        }<br \/>\n        .file-name {<br \/>\n            font-weight: 600;<br \/>\n            color: #1f2937;<br \/>\n            font-size: 14px;<br \/>\n            white-space: nowrap;<br \/>\n            overflow: hidden;<br \/>\n            text-overflow: ellipsis;<br \/>\n        }<br \/>\n        .file-meta {<br \/>\n            font-size: 12px;<br \/>\n            color: #9ca3af;<br \/>\n            margin-top: 2px;<br \/>\n        }<br \/>\n        .file-link {<br \/>\n            color: #3b82f6;<br \/>\n            font-size: 13px;<br \/>\n            text-decoration: none;<br \/>\n            flex-shrink: 0;<br \/>\n            padding: 4px 10px;<br \/>\n            border: 1px solid #3b82f6;<br \/>\n            border-radius: 4px;<br \/>\n            transition: all 0.2s;<br \/>\n        }<br \/>\n        .file-link:hover {<br \/>\n            background: #3b82f6;<br \/>\n            color: #fff;<br \/>\n        }<\/p>\n<p>        \/* &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; \u8f93\u5165\u533a\u57df &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; *\/<br \/>\n        .chat-input-area {<br \/>\n            padding: 16px 20px;<br \/>\n            background: #fff;<br \/>\n            border-top: 1px solid #e5e7eb;<br \/>\n            display: flex;<br \/>\n            gap: 10px;<br \/>\n            align-items: flex-end;<br \/>\n        }<br \/>\n        .chat-input-area textarea {<br \/>\n            flex: 1;<br \/>\n            resize: none;<br \/>\n            border: 1px solid #d1d5db;<br \/>\n            border-radius: 10px;<br \/>\n            padding: 12px 14px;<br \/>\n            font-size: 15px;<br \/>\n            font-family: inherit;<br \/>\n            outline: none;<br \/>\n            min-height: 46px;<br \/>\n            max-height: 120px;<br \/>\n            transition: border-color 0.2s;<br \/>\n        }<br \/>\n        .chat-input-area textarea:focus {<br \/>\n            border-color: #3b82f6;<br \/>\n            box-shadow: 0 0 0 3px rgba(59,130,246,0.1);<br \/>\n        }<br \/>\n        .chat-input-area button {<br \/>\n            width: 66px;<br \/>\n            height: 46px;<br \/>\n            background: linear-gradient(135deg, #3b82f6, #6366f1);<br \/>\n            color: #fff;<br \/>\n            border: none;<br \/>\n            border-radius: 10px;<br \/>\n            font-size: 15px;<br \/>\n            font-weight: 600;<br \/>\n            cursor: pointer;<br \/>\n            transition: opacity 0.2s, transform 0.1s;<br \/>\n            flex-shrink: 0;<br \/>\n        }<br \/>\n        .chat-input-area button:hover { opacity: 0.9; }<br \/>\n        .chat-input-area button:active { transform: scale(0.96); }<br \/>\n        .chat-input-area button:disabled {<br \/>\n            opacity: 0.5;<br \/>\n            cursor: not-allowed;<br \/>\n        }<br \/>\n    &lt;\/style&gt;<br \/>\n&lt;\/head&gt;<br \/>\n&lt;body&gt;<br \/>\n    &lt;div class&#061;&#034;chat-container&#034;&gt;<br \/>\n        &lt;div class&#061;&#034;chat-header&#034;&gt;\u667a\u8c31 AI \u804a\u5929\u52a9\u624b&lt;\/div&gt;<br \/>\n        &lt;div class&#061;&#034;chat-messages&#034; id&#061;&#034;messages&#034;&gt;&lt;\/div&gt;<br \/>\n        &lt;div class&#061;&#034;chat-input-area&#034;&gt;<br \/>\n            &lt;textarea<br \/>\n                id&#061;&#034;userInput&#034;<br \/>\n                rows&#061;&#034;1&#034;<br \/>\n                placeholder&#061;&#034;\u8f93\u5165\u4f60\u7684\u95ee\u9898&#xff0c;\u6309 Enter \u53d1\u9001&#8230;&#034;<br \/>\n            &gt;&lt;\/textarea&gt;<br \/>\n            &lt;button id&#061;&#034;sendBtn&#034; onclick&#061;&#034;sendMessage()&#034;&gt;\u53d1\u9001&lt;\/button&gt;<br \/>\n        &lt;\/div&gt;<br \/>\n    &lt;\/div&gt;<\/p>\n<p>    &lt;script&gt;<br \/>\n        \/\/ &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061; Markdown \u6e32\u67d3&#xff1a;\u4f18\u5148 marked.js&#xff0c;\u515c\u5e95\u81ea\u5efa\u89e3\u6790\u5668 &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<br \/>\n        var usingMarked &#061; (typeof marked !&#061;&#061; &#039;undefined&#039;);<\/p>\n<p>        if (usingMarked) {<br \/>\n            marked.setOptions({<br \/>\n                breaks: true,<br \/>\n                gfm: true,<br \/>\n                sanitize: false<br \/>\n            });<br \/>\n        }<\/p>\n<p>        \/\/ \u7b80\u6613 Markdown \u2192 HTML&#xff08;\u515c\u5e95\u65b9\u6848&#xff0c;\u8986\u76d6\u8868\u683c\u3001\u4ee3\u7801\u5757\u3001\u5e38\u89c1\u683c\u5f0f&#xff09;<br \/>\n        function simpleMarkdown(text) {<br \/>\n            var html &#061; text;<\/p>\n<p>            \/\/ \u8f6c\u4e49 HTML<br \/>\n            html &#061; html.replace(\/&amp;\/g, &#039;&amp;amp;&#039;).replace(\/&lt;\/g, &#039;&amp;lt;&#039;).replace(\/&gt;\/g, &#039;&amp;gt;&#039;);<\/p>\n<p>            \/\/ \u4ee3\u7801\u5757 &#096;&#096;&#096;&#8230;&#096;&#096;&#096;<br \/>\n            html &#061; html.replace(\/&#096;&#096;&#096;(\\\\w*)\\\\n([\\\\s\\\\S]*?)&#096;&#096;&#096;\/g, function(m, lang, code) {<br \/>\n                return &#039;&lt;pre&gt;&lt;code&gt;&#039; &#043; code.replace(\/\\\\n$\/, &#039;&#039;) &#043; &#039;&lt;\/code&gt;&lt;\/pre&gt;&#039;;<br \/>\n            });<\/p>\n<p>            \/\/ \u884c\u5185\u4ee3\u7801 &#096;&#8230;&#096;<br \/>\n            html &#061; html.replace(\/&#096;([^&#096;]&#043;)&#096;\/g, &#039;&lt;code&gt;$1&lt;\/code&gt;&#039;);<\/p>\n<p>            \/\/ \u8868\u683c&#xff1a;\u9010\u884c\u5904\u7406<br \/>\n            html &#061; html.replace(\/(\\\\|[^\\\\n]&#043;\\\\|\\\\n\\\\|[-:| ]&#043;\\\\|\\\\n(?:\\\\|[^\\\\n]&#043;\\\\|\\\\n?)*)\/g, function(tableBlock) {<br \/>\n                var lines &#061; tableBlock.trim().split(&#039;\\\\n&#039;);<br \/>\n                var htmlTable &#061; &#039;&lt;div class&#061;&#034;table-wrapper&#034;&gt;&lt;table&gt;&#039;;<br \/>\n                var isHeader &#061; true;<br \/>\n                for (var i &#061; 0; i &lt; lines.length; i&#043;&#043;) {<br \/>\n                    \/\/ \u8df3\u8fc7\u5206\u9694\u884c<br \/>\n                    if (\/^\\\\|[-:| ]&#043;\\\\|$\/.test(lines[i])) { isHeader &#061; false; continue; }<br \/>\n                    var cells &#061; lines[i].replace(\/^\\\\||\\\\|$\/g, &#039;&#039;).split(&#039;|&#039;);<br \/>\n                    var tag &#061; isHeader ? &#039;th&#039; : &#039;td&#039;;<br \/>\n                    htmlTable &#043;&#061; &#039;&lt;tr&gt;&#039;;<br \/>\n                    for (var j &#061; 0; j &lt; cells.length; j&#043;&#043;) {<br \/>\n                        htmlTable &#043;&#061; &#039;&lt;&#039; &#043; tag &#043; &#039;&gt;&#039; &#043; cells[j].trim() &#043; &#039;&lt;\/&#039; &#043; tag &#043; &#039;&gt;&#039;;<br \/>\n                    }<br \/>\n                    htmlTable &#043;&#061; &#039;&lt;\/tr&gt;&#039;;<br \/>\n                }<br \/>\n                htmlTable &#043;&#061; &#039;&lt;\/table&gt;&lt;\/div&gt;&#039;;<br \/>\n                return htmlTable;<br \/>\n            });<\/p>\n<p>            \/\/ \u6807\u9898<br \/>\n            html &#061; html.replace(\/^###### (.&#043;)$\/gm, &#039;&lt;h6&gt;$1&lt;\/h6&gt;&#039;);<br \/>\n            html &#061; html.replace(\/^##### (.&#043;)$\/gm, &#039;&lt;h5&gt;$1&lt;\/h5&gt;&#039;);<br \/>\n            html &#061; html.replace(\/^#### (.&#043;)$\/gm, &#039;&lt;h4&gt;$1&lt;\/h4&gt;&#039;);<br \/>\n            html &#061; html.replace(\/^### (.&#043;)$\/gm, &#039;&lt;h3&gt;$1&lt;\/h3&gt;&#039;);<br \/>\n            html &#061; html.replace(\/^## (.&#043;)$\/gm, &#039;&lt;h2&gt;$1&lt;\/h2&gt;&#039;);<br \/>\n            html &#061; html.replace(\/^# (.&#043;)$\/gm, &#039;&lt;h1&gt;$1&lt;\/h1&gt;&#039;);<\/p>\n<p>            \/\/ \u52a0\u7c97\u548c\u659c\u4f53<br \/>\n            html &#061; html.replace(\/\\\\*\\\\*\\\\*(.&#043;?)\\\\*\\\\*\\\\*\/g, &#039;&lt;strong&gt;&lt;em&gt;$1&lt;\/em&gt;&lt;\/strong&gt;&#039;);<br \/>\n            html &#061; html.replace(\/\\\\*\\\\*(.&#043;?)\\\\*\\\\*\/g, &#039;&lt;strong&gt;$1&lt;\/strong&gt;&#039;);<br \/>\n            html &#061; html.replace(\/\\\\*(.&#043;?)\\\\*\/g, &#039;&lt;em&gt;$1&lt;\/em&gt;&#039;);<\/p>\n<p>            \/\/ \u56fe\u7247<br \/>\n            html &#061; html.replace(\/!\\\\[([^\\\\]]*)\\\\]\\\\(([^)]&#043;)\\\\)\/g, &#039;&lt;img src&#061;&#034;$2&#034; alt&#061;&#034;$1&#034; style&#061;&#034;max-width:100%;&#034;&gt;&#039;);<\/p>\n<p>            \/\/ \u94fe\u63a5<br \/>\n            html &#061; html.replace(\/\\\\[([^\\\\]]&#043;)\\\\]\\\\(([^)]&#043;)\\\\)\/g, &#039;&lt;a href&#061;&#034;$2&#034; target&#061;&#034;_blank&#034;&gt;$1&lt;\/a&gt;&#039;);<\/p>\n<p>            \/\/ \u5f15\u7528<br \/>\n            html &#061; html.replace(\/^&amp;gt; (.&#043;)$\/gm, &#039;&lt;blockquote&gt;$1&lt;\/blockquote&gt;&#039;);<\/p>\n<p>            \/\/ \u5206\u5272\u7ebf<br \/>\n            html &#061; html.replace(\/^&#8212;$\/gm, &#039;&lt;hr&gt;&#039;);<\/p>\n<p>            \/\/ \u65e0\u5e8f\u5217\u8868<br \/>\n            html &#061; html.replace(\/^[\\\\-\\\\*] (.&#043;)$\/gm, &#039;&lt;li&gt;$1&lt;\/li&gt;&#039;);<br \/>\n            html &#061; html.replace(\/(&lt;li&gt;.*&lt;\\\\\/li&gt;\\\\n?)&#043;\/g, &#039;&lt;ul&gt;$&amp;&lt;\/ul&gt;&#039;);<\/p>\n<p>            \/\/ \u6709\u5e8f\u5217\u8868<br \/>\n            html &#061; html.replace(\/^\\\\d&#043;\\\\. (.&#043;)$\/gm, &#039;&lt;li&gt;$1&lt;\/li&gt;&#039;);<\/p>\n<p>            \/\/ \u6362\u884c<br \/>\n            html &#061; html.replace(\/\\\\n\\\\n\/g, &#039;&lt;\/p&gt;&lt;p&gt;&#039;);<br \/>\n            html &#061; html.replace(\/\\\\n\/g, &#039;&lt;br&gt;&#039;);<br \/>\n            html &#061; &#039;&lt;p&gt;&#039; &#043; html &#043; &#039;&lt;\/p&gt;&#039;;<\/p>\n<p>            \/\/ \u6e05\u7406\u7a7a\u6bb5\u843d\u548c\u591a\u4f59\u5d4c\u5957<br \/>\n            html &#061; html.replace(\/&lt;p&gt;&lt;\\\\\/p&gt;\/g, &#039;&#039;);<br \/>\n            html &#061; html.replace(\/&lt;p&gt;&lt;(h[1-6]|ul|ol|pre|blockquote|hr|table)\/g, &#039;&lt;$1&#039;);<br \/>\n            html &#061; html.replace(\/&lt;\\\\\/(h[1-6]|ul|ol|pre|blockquote|table)&gt;&lt;\\\\\/p&gt;\/g, &#039;&lt;\/$1&gt;&#039;);<\/p>\n<p>            return html;<br \/>\n        }<\/p>\n<p>        function renderMarkdown(text) {<br \/>\n            if (usingMarked) {<br \/>\n                var html &#061; marked.parse(text);<br \/>\n                html &#061; html.replace(\/&lt;table&gt;\/g, &#039;&lt;div class&#061;&#034;table-wrapper&#034;&gt;&lt;table&gt;&#039;);<br \/>\n                html &#061; html.replace(\/&lt;\\\\\/table&gt;\/g, &#039;&lt;\/table&gt;&lt;\/div&gt;&#039;);<br \/>\n                return html;<br \/>\n            } else {<br \/>\n                return simpleMarkdown(text);<br \/>\n            }<br \/>\n        }<\/p>\n<p>        \/\/ \u68c0\u6d4b\u5e76\u683c\u5f0f\u5316\u6587\u4ef6\u4fe1\u606f&#xff08;\u667a\u8c31\u8fd4\u56de\u7684\u94fe\u63a5\/\u6587\u4ef6\u5f15\u7528&#xff09;<br \/>\n        function formatFileInfo(text) {<br \/>\n            \/\/ \u5339\u914d\u56fe\u7247\u94fe\u63a5<br \/>\n            text &#061; text.replace(<br \/>\n                \/!\\\\[([^\\\\]]*)\\\\]\\\\(([^)]&#043;)\\\\)\/g,<br \/>\n                &#039;&lt;div class&#061;&#034;file-card&#034;&gt;&#039; &#043;<br \/>\n                &#039;&lt;div class&#061;&#034;file-icon&#034;&gt;IMG&lt;\/div&gt;&#039; &#043;<br \/>\n                &#039;&lt;div class&#061;&#034;file-info&#034;&gt;&lt;div class&#061;&#034;file-name&#034;&gt;$1&lt;\/div&gt;&lt;div class&#061;&#034;file-meta&#034;&gt;\u56fe\u7247\u6587\u4ef6&lt;\/div&gt;&lt;\/div&gt;&#039; &#043;<br \/>\n                &#039;&lt;a class&#061;&#034;file-link&#034; href&#061;&#034;$2&#034; target&#061;&#034;_blank&#034;&gt;\u67e5\u770b&lt;\/a&gt;&#039; &#043;<br \/>\n                &#039;&lt;\/div&gt;&#039;<br \/>\n            );<\/p>\n<p>            \/\/ \u5339\u914d\u5e38\u89c1\u6587\u4ef6\u94fe\u63a5 (.pdf, .doc, .xlsx, .zip \u7b49)<br \/>\n            text &#061; text.replace(<br \/>\n                \/\\\\[([^\\\\]]&#043;)\\\\]\\\\((https?:\\\\\/\\\\\/[^)]&#043;\\\\.(pdf|docx?|xlsx?|pptx?|zip|rar|txt|csv|json|xml))\\\\)\/gi,<br \/>\n                function(match, name, url, ext) {<br \/>\n                    var extUpper &#061; ext.toUpperCase();<br \/>\n                    return &#039;&lt;div class&#061;&#034;file-card&#034;&gt;&#039; &#043;<br \/>\n                        &#039;&lt;div class&#061;&#034;file-icon&#034;&gt;&#039; &#043; extUpper &#043; &#039;&lt;\/div&gt;&#039; &#043;<br \/>\n                        &#039;&lt;div class&#061;&#034;file-info&#034;&gt;&lt;div class&#061;&#034;file-name&#034;&gt;&#039; &#043; name &#043; &#039;&lt;\/div&gt;&lt;div class&#061;&#034;file-meta&#034;&gt;&#039; &#043; extUpper &#043; &#039; \u6587\u4ef6&lt;\/div&gt;&lt;\/div&gt;&#039; &#043;<br \/>\n                        &#039;&lt;a class&#061;&#034;file-link&#034; href&#061;&#034;&#039; &#043; url &#043; &#039;&#034; target&#061;&#034;_blank&#034;&gt;\u4e0b\u8f7d&lt;\/a&gt;&#039; &#043;<br \/>\n                        &#039;&lt;\/div&gt;&#039;;<br \/>\n                }<br \/>\n            );<\/p>\n<p>            return text;<br \/>\n        }<\/p>\n<p>        const messagesDiv &#061; document.getElementById(&#039;messages&#039;);<br \/>\n        const userInput &#061; document.getElementById(&#039;userInput&#039;);<br \/>\n        const sendBtn &#061; document.getElementById(&#039;sendBtn&#039;);<\/p>\n<p>        const conversation &#061; []; \/\/ \u4fdd\u5b58\u5bf9\u8bdd\u5386\u53f2<\/p>\n<p>        \/\/ \u6dfb\u52a0\u6d88\u606f\u5230\u754c\u9762<br \/>\n        function addMessage(role, content, isLoading) {<br \/>\n            const msgDiv &#061; document.createElement(&#039;div&#039;);<br \/>\n            msgDiv.className &#061; &#039;message &#039; &#043; role &#043; (isLoading ? &#039; loading&#039; : &#039;&#039;);<\/p>\n<p>            if (role &#061;&#061;&#061; &#039;assistant&#039; &amp;&amp; !isLoading) {<br \/>\n                \/\/ \u52a9\u624b\u6d88\u606f&#xff1a;Markdown \u2192 HTML<br \/>\n                let formatted &#061; formatFileInfo(content);  \/\/ \u5148\u5904\u7406\u6587\u4ef6\u4fe1\u606f<br \/>\n                let html &#061; renderMarkdown(formatted);      \/\/ \u518d\u6e32\u67d3 Markdown<br \/>\n                msgDiv.innerHTML &#061; html;<\/p>\n<p>                \/\/ \u8ba9\u6240\u6709\u94fe\u63a5\u5728\u65b0\u6807\u7b7e\u9875\u6253\u5f00<br \/>\n                msgDiv.querySelectorAll(&#039;a&#039;).forEach(function(a) {<br \/>\n                    a.setAttribute(&#039;target&#039;, &#039;_blank&#039;);<br \/>\n                    a.setAttribute(&#039;rel&#039;, &#039;noopener noreferrer&#039;);<br \/>\n                });<br \/>\n            } else {<br \/>\n                \/\/ \u7528\u6237\u6d88\u606f\u548c\u52a0\u8f7d\u63d0\u793a\u4fdd\u6301\u7eaf\u6587\u672c<br \/>\n                msgDiv.textContent &#061; content;<br \/>\n            }<\/p>\n<p>            messagesDiv.appendChild(msgDiv);<br \/>\n            messagesDiv.scrollTop &#061; messagesDiv.scrollHeight;<br \/>\n            return msgDiv;<br \/>\n        }<\/p>\n<p>        \/\/ \u53d1\u9001\u6d88\u606f<br \/>\n        async function sendMessage() {<br \/>\n            const content &#061; userInput.value.trim();<br \/>\n            if (!content) return;<\/p>\n<p>            \/\/ \u7981\u7528\u6309\u94ae<br \/>\n            sendBtn.disabled &#061; true;<br \/>\n            userInput.disabled &#061; true;<\/p>\n<p>            \/\/ \u663e\u793a\u7528\u6237\u6d88\u606f<br \/>\n            addMessage(&#039;user&#039;, content);<br \/>\n            conversation.push({ role: &#039;user&#039;, content: content });<br \/>\n            userInput.value &#061; &#039;&#039;;<br \/>\n            userInput.style.height &#061; &#039;auto&#039;;<\/p>\n<p>            \/\/ \u663e\u793a\u52a0\u8f7d\u63d0\u793a<br \/>\n            const loadingMsg &#061; addMessage(&#039;assistant&#039;, &#039;AI \u6b63\u5728\u601d\u8003&#8230;&#039;, true);<\/p>\n<p>            try {<br \/>\n                const response &#061; await fetch(&#039;http:\/\/localhost:3000\/chat&#039;, {<br \/>\n                    method: &#039;POST&#039;,<br \/>\n                    headers: { &#039;Content-Type&#039;: &#039;application\/json&#039; },<br \/>\n                    body: JSON.stringify({ messages: conversation })<br \/>\n                });<\/p>\n<p>                if (!response.ok) {<br \/>\n                    throw new Error(&#039;\u8bf7\u6c42\u5931\u8d25: &#039; &#043; response.status);<br \/>\n                }<\/p>\n<p>                const data &#061; await response.json();<\/p>\n<p>                \/\/ \u79fb\u9664\u52a0\u8f7d\u63d0\u793a<br \/>\n                loadingMsg.remove();<\/p>\n<p>                const reply &#061; data.choices[0].message.content;<br \/>\n                addMessage(&#039;assistant&#039;, reply);<br \/>\n                conversation.push({ role: &#039;assistant&#039;, content: reply });<\/p>\n<p>            } catch (err) {<br \/>\n                loadingMsg.remove();<br \/>\n                addMessage(&#039;assistant&#039;, &#039;\u51fa\u9519\u4e86: &#039; &#043; err.message &#043; &#039;\\\\n\u8bf7\u786e\u4fdd\u5df2\u542f\u52a8 node server.js&#039;);<br \/>\n                console.error(err);<br \/>\n            }<\/p>\n<p>            \/\/ \u6062\u590d\u6309\u94ae<br \/>\n            sendBtn.disabled &#061; false;<br \/>\n            userInput.disabled &#061; false;<br \/>\n            userInput.focus();<br \/>\n        }<\/p>\n<p>        \/\/ Enter \u53d1\u9001&#xff0c;Shift&#043;Enter \u6362\u884c<br \/>\n        userInput.addEventListener(&#039;keydown&#039;, function(e) {<br \/>\n            if (e.key &#061;&#061;&#061; &#039;Enter&#039; &amp;&amp; !e.shiftKey) {<br \/>\n                e.preventDefault();<br \/>\n                sendMessage();<br \/>\n            }<br \/>\n        });<\/p>\n<p>        \/\/ \u81ea\u52a8\u8c03\u6574\u8f93\u5165\u6846\u9ad8\u5ea6<br \/>\n        userInput.addEventListener(&#039;input&#039;, function() {<br \/>\n            this.style.height &#061; &#039;auto&#039;;<br \/>\n            this.style.height &#061; Math.min(this.scrollHeight, 120) &#043; &#039;px&#039;;<br \/>\n        });<br \/>\n    &lt;\/script&gt;<br \/>\n&lt;\/body&gt;<br \/>\n&lt;\/html&gt;<\/p>\n<h2 style=\"background-color:transparent\">CSS\u6e90\u7801<\/h2>\n<p>\/**<br \/>\n * \u667a\u8c31 AI \u804a\u5929\u4ee3\u7406\u670d\u52a1\u5668<br \/>\n * &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<br \/>\n * \u4f5c\u7528&#xff1a;\u524d\u7aef\u9875\u9762\u901a\u8fc7\u672c\u4ee3\u7406\u8f6c\u53d1\u8bf7\u6c42\u5230\u667a\u8c31 API&#xff0c;\u89e3\u51b3\u4e24\u4e2a\u95ee\u9898&#xff1a;<br \/>\n *   1. CORS \u8de8\u57df \u2014\u2014 \u6d4f\u89c8\u5668\u4e0d\u80fd\u76f4\u63a5\u8c03 open.bigmodel.cn&#xff0c;\u4ee3\u7406\u65e0\u6b64\u9650\u5236<br \/>\n *   2. API Key \u5b89\u5168 \u2014\u2014 Key \u53ea\u4fdd\u5b58\u5728\u670d\u52a1\u7aef&#xff0c;\u4e0d\u4f1a\u66b4\u9732\u7ed9\u524d\u7aef<br \/>\n *<br \/>\n * \u4f7f\u7528&#xff1a;node server.js  \u7136\u540e\u6253\u5f00 \u667a\u8c31\u804a\u5929.html<br \/>\n * &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<br \/>\n *\/<\/p>\n<p>\/\/ http  &#xff1a;\u521b\u5efa\u672c\u5730\u670d\u52a1&#xff0c;\u63a5\u6536\u524d\u7aef\u8bf7\u6c42<br \/>\n\/\/ https &#xff1a;\u8f6c\u53d1\u8bf7\u6c42\u5230\u667a\u8c31 API&#xff08;\u667a\u8c31\u7528 HTTPS&#xff09;<br \/>\nconst http &#061; require(&#039;http&#039;);<br \/>\nconst https &#061; require(&#039;https&#039;);<\/p>\n<p>\/\/ &#8212;- \u914d\u7f6e &#8212;-<br \/>\nconst PORT &#061; 3000; \/\/ \u4ee3\u7406\u76d1\u542c\u7aef\u53e3<br \/>\nconst API_KEY &#061; &#039;\u4f60\u7684 API Key&#039;<br \/>\n\/\/ \u667a\u8c31 API Key&#xff08;\u4ece https:\/\/open.bigmodel.cn \u83b7\u53d6&#xff09;<\/p>\n<p>\/**<br \/>\n * \u521b\u5efa HTTP \u670d\u52a1\u5668<br \/>\n * \u5de5\u4f5c\u6d41\u7a0b&#xff1a;\u524d\u7aef fetch \u2192 \u672c\u4ee3\u7406 \u2192 \u667a\u8c31 API \u2192 \u672c\u4ee3\u7406 \u2192 \u524d\u7aef<br \/>\n *\/<br \/>\nconst server &#061; http.createServer((req, res) &#061;&gt; {<\/p>\n<p>    \/\/ &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<br \/>\n    \/\/ \u7b2c\u4e00\u6b65&#xff1a;\u8bbe\u7f6e CORS \u54cd\u5e94\u5934<br \/>\n    \/\/ \u5141\u8bb8\u4efb\u610f\u6765\u6e90\u7684\u524d\u7aef\u9875\u9762\u8c03\u7528\u672c\u4ee3\u7406<br \/>\n    \/\/ &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<br \/>\n    res.setHeader(&#039;Access-Control-Allow-Origin&#039;, &#039;*&#039;);          \/\/ \u5141\u8bb8\u6240\u6709\u57df\u540d<br \/>\n    res.setHeader(&#039;Access-Control-Allow-Methods&#039;, &#039;POST, OPTIONS&#039;); \/\/ \u5141\u8bb8\u7684\u8bf7\u6c42\u65b9\u6cd5<br \/>\n    res.setHeader(&#039;Access-Control-Allow-Headers&#039;, &#039;Content-Type&#039;);  \/\/ \u5141\u8bb8\u7684\u8bf7\u6c42\u5934<\/p>\n<p>    \/\/ &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<br \/>\n    \/\/ \u7b2c\u4e8c\u6b65&#xff1a;\u5904\u7406\u6d4f\u89c8\u5668\u9884\u68c0\u8bf7\u6c42&#xff08;OPTIONS&#xff09;<br \/>\n    \/\/ \u6d4f\u89c8\u5668\u5728\u53d1\u9001 POST \u524d\u4f1a\u5148\u53d1 OPTIONS \u8bd5\u63a2&#xff0c;\u76f4\u63a5\u8fd4\u56de 200 \u5373\u53ef<br \/>\n    \/\/ &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<br \/>\n    if (req.method &#061;&#061;&#061; &#039;OPTIONS&#039;) {<br \/>\n        res.writeHead(200);<br \/>\n        res.end();<br \/>\n        return;<br \/>\n    }<\/p>\n<p>    \/\/ &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<br \/>\n    \/\/ \u7b2c\u4e09\u6b65&#xff1a;\u5904\u7406 \/chat \u804a\u5929\u63a5\u53e3<br \/>\n    \/\/ \u524d\u7aef POST \u5230\u6b64\u8def\u5f84&#xff0c;\u643a\u5e26\u5bf9\u8bdd\u5386\u53f2<br \/>\n    \/\/ &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<br \/>\n    if (req.method &#061;&#061;&#061; &#039;POST&#039; &amp;&amp; req.url &#061;&#061;&#061; &#039;\/chat&#039;) {<br \/>\n        let body &#061; &#039;&#039;;<\/p>\n<p>        \/\/ \u5206\u6bb5\u63a5\u6536\u524d\u7aef\u4f20\u6765\u7684\u8bf7\u6c42\u4f53\u6570\u636e<br \/>\n        req.on(&#039;data&#039;, chunk &#061;&gt; {<br \/>\n            body &#043;&#061; chunk.toString();<br \/>\n        });<\/p>\n<p>        \/\/ \u63a5\u6536\u5b8c\u6bd5\u540e&#xff0c;\u8f6c\u53d1\u7ed9\u667a\u8c31 API<br \/>\n        req.on(&#039;end&#039;, () &#061;&gt; {<br \/>\n            \/\/ \u6784\u9020\u53d1\u7ed9\u667a\u8c31\u7684\u8bf7\u6c42\u4f53<br \/>\n            \/\/ model: \u6a21\u578b\u540d\u79f0&#xff0c;GLM-4.5-Flash \u662f\u8f7b\u91cf\u5feb\u901f\u7248<br \/>\n            \/\/ stream: false \u8868\u793a\u4e00\u6b21\u6027\u8fd4\u56de&#xff08;\u975e\u6d41\u5f0f&#xff09;&#xff0c;\u524d\u7aef\u5904\u7406\u66f4\u7b80\u5355<br \/>\n            const postData &#061; JSON.stringify({<br \/>\n                model: &#039;GLM-4.5-Flash&#039;,<br \/>\n                stream: false,<br \/>\n                messages: JSON.parse(body).messages \/\/ \u900f\u4f20\u524d\u7aef\u7684\u5bf9\u8bdd\u5386\u53f2<br \/>\n            });<\/p>\n<p>            \/\/ \u667a\u8c31 API \u8bf7\u6c42\u914d\u7f6e<br \/>\n            const options &#061; {<br \/>\n                hostname: &#039;open.bigmodel.cn&#039;,                         \/\/ \u667a\u8c31 API \u57df\u540d<br \/>\n                path: &#039;\/api\/paas\/v4\/chat\/completions&#039;,               \/\/ \u804a\u5929\u8865\u5168\u63a5\u53e3\u8def\u5f84<br \/>\n                method: &#039;POST&#039;,<br \/>\n                headers: {<br \/>\n                    &#039;Content-Type&#039;: &#039;application\/json&#039;,<br \/>\n                    &#039;Authorization&#039;: &#096;Bearer ${API_KEY}&#096;,            \/\/ Bearer Token \u9274\u6743<br \/>\n                    &#039;Content-Length&#039;: Buffer.byteLength(postData)    \/\/ \u8bbe\u7f6e\u8bf7\u6c42\u4f53\u957f\u5ea6&#xff08;\u5fc5\u9700&#xff09;<br \/>\n                }<br \/>\n            };<\/p>\n<p>            \/\/ \u53d1\u8d77 HTTPS \u8bf7\u6c42\u5230\u667a\u8c31<br \/>\n            const proxyReq &#061; https.request(options, proxyRes &#061;&gt; {<br \/>\n                let data &#061; &#039;&#039;;<\/p>\n<p>                \/\/ \u63a5\u6536\u667a\u8c31\u7684\u5206\u6bb5\u54cd\u5e94<br \/>\n                proxyRes.on(&#039;data&#039;, chunk &#061;&gt; {<br \/>\n                    data &#043;&#061; chunk.toString();<br \/>\n                });<\/p>\n<p>                \/\/ \u54cd\u5e94\u63a5\u6536\u5b8c\u6bd5&#xff0c;\u539f\u6837\u8fd4\u56de\u7ed9\u524d\u7aef<br \/>\n                proxyRes.on(&#039;end&#039;, () &#061;&gt; {<br \/>\n                    res.writeHead(proxyRes.statusCode, {<br \/>\n                        &#039;Content-Type&#039;: &#039;application\/json&#039;<br \/>\n                    });<br \/>\n                    res.end(data); \/\/ \u667a\u8c31\u7684\u54cd\u5e94\u76f4\u63a5\u900f\u4f20\u7ed9\u524d\u7aef<br \/>\n                });<br \/>\n            });<\/p>\n<p>            \/\/ \u7f51\u7edc\u9519\u8bef\u5904\u7406&#xff1a;\u667a\u8c31\u670d\u52a1\u4e0d\u53ef\u8fbe\u6216\u8d85\u65f6<br \/>\n            proxyReq.on(&#039;error&#039;, err &#061;&gt; {<br \/>\n                console.error(&#039;\u4ee3\u7406\u8bf7\u6c42\u51fa\u9519:&#039;, err.message);<br \/>\n                res.writeHead(500, { &#039;Content-Type&#039;: &#039;application\/json&#039; });<br \/>\n                res.end(JSON.stringify({ error: &#039;\u670d\u52a1\u5668\u51fa\u9519: &#039; &#043; err.message }));<br \/>\n            });<\/p>\n<p>            \/\/ \u53d1\u9001\u8bf7\u6c42\u4f53\u5e76\u7ed3\u675f\u8bf7\u6c42<br \/>\n            proxyReq.write(postData);<br \/>\n            proxyReq.end();<br \/>\n        });<\/p>\n<p>    } else {<br \/>\n        \/\/ &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<br \/>\n        \/\/ \u5176\u4ed6\u8def\u5f84\u4e00\u5f8b\u8fd4\u56de 404<br \/>\n        \/\/ &#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;&#061;<br \/>\n        res.writeHead(404, { &#039;Content-Type&#039;: &#039;text\/plain&#039; });<br \/>\n        res.end(&#039;Not Found&#039;);<br \/>\n    }<br \/>\n});<\/p>\n<p>\/\/ \u542f\u52a8\u670d\u52a1\u5668&#xff0c;\u76d1\u542c 3000 \u7aef\u53e3<br \/>\nserver.listen(PORT, () &#061;&gt; {<br \/>\n    console.log(&#096;\u4ee3\u7406\u670d\u52a1\u5668\u5df2\u542f\u52a8: http:\/\/localhost:${PORT}\/chat&#096;);<br \/>\n    console.log(&#039;\u8bf7\u5728\u6d4f\u89c8\u5668\u4e2d\u6253\u5f00 \u667a\u8c31\u804a\u5929.html&#039;);<br \/>\n});<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4e0a\u56fe&#xff01;&#xff01;&#xff01;HTML\u6e90\u7801<\/p>\n<p><title>\u667a\u8c31 AI \u804a\u5929\u52a9\u624b<\/title>&lt;!&#8211; marked.js: Markdown \u8f6c HTML&#xff08;\u56fd\u5185 CDN  \u81ea\u5efa\u515c\u5e95&amp;#xf<\/p>\n","protected":false},"author":2,"featured_media":85668,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[722,187,190],"topic":[],"class_list":["post-85669","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-server","tag-ecmascript","tag-javascript","tag-190"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u667a\u8c31AI\u8c03\u7528\uff08FETCH+NODE+JS\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.wsisp.com\/helps\/85669.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u667a\u8c31AI\u8c03\u7528\uff08FETCH+NODE+JS\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"\u4e0a\u56fe&#xff01;&#xff01;&#xff01;HTML\u6e90\u7801 \u667a\u8c31 AI \u804a\u5929\u52a9\u624b&lt;!-- marked.js: Markdown \u8f6c HTML&#xff08;\u56fd\u5185 CDN \u81ea\u5efa\u515c\u5e95&amp;#xf\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/85669.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2026-07-27T12:25:11+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/07\/20260727122510-6a674e26387fb.png\" \/>\n<meta name=\"author\" content=\"admin\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"admin\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"9 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/85669.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/85669.html\",\"name\":\"\u667a\u8c31AI\u8c03\u7528\uff08FETCH+NODE+JS\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2026-07-27T12:25:11+00:00\",\"dateModified\":\"2026-07-27T12:25:11+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/85669.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/85669.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/85669.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u667a\u8c31AI\u8c03\u7528\uff08FETCH+NODE+JS\uff09\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\",\"url\":\"https:\/\/www.wsisp.com\/helps\/\",\"name\":\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"description\":\"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\",\"name\":\"admin\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"contentUrl\":\"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery\",\"caption\":\"admin\"},\"sameAs\":[\"http:\/\/wp.wsisp.com\"],\"url\":\"https:\/\/www.wsisp.com\/helps\/author\/admin\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"\u667a\u8c31AI\u8c03\u7528\uff08FETCH+NODE+JS\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.wsisp.com\/helps\/85669.html","og_locale":"zh_CN","og_type":"article","og_title":"\u667a\u8c31AI\u8c03\u7528\uff08FETCH+NODE+JS\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"\u4e0a\u56fe&#xff01;&#xff01;&#xff01;HTML\u6e90\u7801 \u667a\u8c31 AI \u804a\u5929\u52a9\u624b&lt;!-- marked.js: Markdown \u8f6c HTML&#xff08;\u56fd\u5185 CDN \u81ea\u5efa\u515c\u5e95&amp;#xf","og_url":"https:\/\/www.wsisp.com\/helps\/85669.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2026-07-27T12:25:11+00:00","og_image":[{"url":"https:\/\/www.wsisp.com\/helps\/wp-content\/uploads\/2026\/07\/20260727122510-6a674e26387fb.png"}],"author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"9 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/85669.html","url":"https:\/\/www.wsisp.com\/helps\/85669.html","name":"\u667a\u8c31AI\u8c03\u7528\uff08FETCH+NODE+JS\uff09 - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2026-07-27T12:25:11+00:00","dateModified":"2026-07-27T12:25:11+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/85669.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/85669.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/85669.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"\u667a\u8c31AI\u8c03\u7528\uff08FETCH+NODE+JS\uff09"}]},{"@type":"WebSite","@id":"https:\/\/www.wsisp.com\/helps\/#website","url":"https:\/\/www.wsisp.com\/helps\/","name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","description":"\u9999\u6e2f\u670d\u52a1\u5668_\u9999\u6e2f\u4e91\u670d\u52a1\u5668\u8d44\u8baf_\u670d\u52a1\u5668\u5e2e\u52a9\u6587\u6863_\u670d\u52a1\u5668\u6559\u7a0b","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.wsisp.com\/helps\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41","name":"admin","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/image\/","url":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","contentUrl":"https:\/\/gravatar.wp-china-yes.net\/avatar\/?s=96&d=mystery","caption":"admin"},"sameAs":["http:\/\/wp.wsisp.com"],"url":"https:\/\/www.wsisp.com\/helps\/author\/admin"}]}},"_links":{"self":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/85669","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/comments?post=85669"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/85669\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media\/85668"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=85669"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=85669"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=85669"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=85669"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}