{"id":119147,"date":"2026-10-29T00:48:34","date_gmt":"2026-10-28T16:48:34","guid":{"rendered":"https:\/\/www.wsisp.com\/helps\/119147.html"},"modified":"2026-10-29T00:48:34","modified_gmt":"2026-10-28T16:48:34","slug":"workbuddy_%e4%ba%a7%e7%89%a9%e4%b8%8e%e5%b7%a5%e4%bd%9c%e7%a9%ba%e9%97%b4%e7%ae%a1%e7%90%864_%e4%ba%a7%e7%89%a9%e9%a2%84%e8%a7%88%e4%b8%8e%e6%89%93%e5%bc%80%e6%96%b9%e5%bc%8f","status":"publish","type":"post","link":"https:\/\/www.wsisp.com\/helps\/119147.html","title":{"rendered":"WorkBuddy_\u4ea7\u7269\u4e0e\u5de5\u4f5c\u7a7a\u95f4\u7ba1\u74064_\u4ea7\u7269\u9884\u89c8\u4e0e\u6253\u5f00\u65b9\u5f0f"},"content":{"rendered":"<h2>\u4ea7\u7269\u9884\u89c8\u4e0e\u6253\u5f00\u65b9\u5f0f<\/h2>\n<h3>\u6458\u8981<\/h3>\n<p>\u5728\u73b0\u4ee3\u5f00\u53d1\u5de5\u5177\u3001AI \u7f16\u7a0b\u52a9\u624b\u3001CI\/CD \u5e73\u53f0\u4ee5\u53ca\u5404\u7c7b\u534f\u4f5c\u7cfb\u7edf\u4e2d&#xff0c;&#034;\u4ea7\u7269&#xff08;Artifact&#xff09;&#034;\u662f\u4e00\u4e2a\u9ad8\u9891\u51fa\u73b0\u7684\u6982\u5ff5\u3002\u5b83\u53ef\u80fd\u662f\u7f16\u8bd1\u751f\u6210\u7684\u4e8c\u8fdb\u5236\u6587\u4ef6\u3001\u6784\u5efa\u8f93\u51fa\u7684\u524d\u7aef\u8d44\u6e90\u5305\u3001\u6570\u636e\u5904\u7406\u7684\u4e2d\u95f4\u7ed3\u679c&#xff0c;\u4e5f\u53ef\u80fd\u662f\u4e00\u4efd AI \u751f\u6210\u7684\u62a5\u544a\u6587\u6863\u3002\u4ea7\u7269\u751f\u6210\u4e4b\u540e&#xff0c;\u7528\u6237\u6700\u5173\u5fc3\u7684\u95ee\u9898\u5f80\u5f80\u53ea\u6709\u4e00\u4e2a&#xff1a;\u6211\u8be5\u600e\u4e48\u67e5\u770b\u5b83&#xff1f;<\/p>\n<p>\u672c\u6587\u56f4\u7ed5&#034;\u53f3\u4fa7\u4ea7\u7269\u533a&#034;\u8fd9\u4e00\u5178\u578b\u4ea4\u4e92\u573a\u666f&#xff0c;\u7cfb\u7edf\u8bb2\u89e3\u4ea7\u7269\u9884\u89c8\u3001\u4e0b\u8f7d\u4e0e\u672c\u5730\u5b9a\u4f4d\u7684\u5b8c\u6574\u64cd\u4f5c\u94fe\u8def\u3002\u5185\u5bb9\u6db5\u76d6\u4ea7\u7269\u7c7b\u578b\u8bc6\u522b\u3001\u9884\u89c8\u6e32\u67d3\u7b56\u7565\u3001\u4e0b\u8f7d\u4e0e\u4fdd\u5b58\u673a\u5236\u3001\u672c\u5730\u6587\u4ef6\u5b9a\u4f4d\u3001\u5e38\u89c1\u95ee\u9898\u6392\u67e5&#xff0c;\u5e76\u914d\u6709\u53ef\u76f4\u63a5\u8fd0\u884c\u7684\u4ee3\u7801\u793a\u4f8b\u3002\u65e0\u8bba\u4f60\u662f\u5728\u5f00\u53d1\u4e00\u4e2a\u5e26\u4ea7\u7269\u9762\u677f\u7684 IDE \u63d2\u4ef6&#xff0c;\u8fd8\u662f\u60f3\u641e\u6e05\u695a\u65e5\u5e38\u5de5\u5177\u4e2d\u4ea7\u7269\u533a\u7684\u5de5\u4f5c\u673a\u5236&#xff0c;\u672c\u6587\u90fd\u80fd\u63d0\u4f9b\u53ef\u843d\u5730\u7684\u53c2\u8003\u3002<\/p>\n<hr \/>\n<h3>\u5f15\u8a00<\/h3>\n<h4>\u4e3a\u4ec0\u4e48&#034;\u4ea7\u7269\u533a&#034;\u503c\u5f97\u5355\u72ec\u8ba8\u8bba<\/h4>\n<p>\u5927\u591a\u6570\u5de5\u5177\u628a\u6ce8\u610f\u529b\u653e\u5728&#034;\u5982\u4f55\u751f\u6210\u4ea7\u7269&#034;\u4e0a&#xff0c;\u5374\u5ffd\u7565\u4e86&#034;\u5982\u4f55\u8ba9\u7528\u6237\u6d88\u8d39\u4ea7\u7269&#034;\u3002\u4e00\u4e2a\u8bbe\u8ba1\u826f\u597d\u7684\u4ea7\u7269\u533a&#xff0c;\u9700\u8981\u540c\u65f6\u89e3\u51b3\u4e09\u4e2a\u5c42\u9762\u7684\u95ee\u9898&#xff1a;<\/p>\n<li>\u53ef\u8bfb\u6027&#xff1a;\u7528\u6237\u80fd\u5426\u5728\u4e0d\u4e0b\u8f7d\u7684\u60c5\u51b5\u4e0b\u76f4\u63a5\u770b\u5230\u4ea7\u7269\u5185\u5bb9&#xff1f;<\/li>\n<li>\u53ef\u83b7\u53d6\u6027&#xff1a;\u7528\u6237\u80fd\u5426\u628a\u4ea7\u7269\u4fdd\u5b58\u5230\u672c\u5730&#xff1f;<\/li>\n<li>\u53ef\u8ffd\u6eaf\u6027&#xff1a;\u7528\u6237\u80fd\u5426\u5feb\u901f\u5b9a\u4f4d\u5230\u4ea7\u7269\u5728\u672c\u5730\u78c1\u76d8\u4e0a\u7684\u771f\u5b9e\u8def\u5f84&#xff1f;<\/li>\n<p>\u8fd9\u4e09\u8005\u5206\u522b\u5bf9\u5e94\u9884\u89c8&#xff08;Preview&#xff09;\u3001\u4e0b\u8f7d&#xff08;Download&#xff09;\u3001\u5b9a\u4f4d&#xff08;Reveal in File System&#xff09; \u4e09\u79cd\u64cd\u4f5c\u3002\u770b\u4f3c\u7b80\u5355&#xff0c;\u5b9e\u9645\u5b9e\u73b0\u65f6\u4f1a\u9047\u5230\u6587\u4ef6\u7c7b\u578b\u5224\u65ad\u3001\u6d4f\u89c8\u5668\u5b89\u5168\u9650\u5236\u3001\u5927\u6587\u4ef6\u6027\u80fd\u3001\u8def\u5f84\u6620\u5c04\u7b49\u8bf8\u591a\u7ec6\u8282\u95ee\u9898\u3002<\/p>\n<h4>\u672c\u6587\u7684\u7ec4\u7ec7\u65b9\u5f0f<\/h4>\n<p>\u4e0b\u6587\u6309\u7167&#034;\u8bc6\u522b \u2192 \u9884\u89c8 \u2192 \u4e0b\u8f7d \u2192 \u5b9a\u4f4d \u2192 \u6392\u9519&#034;\u7684\u987a\u5e8f\u5c55\u5f00&#xff0c;\u6bcf\u4e00\u8282\u90fd\u914d\u6709\u4ee3\u7801\u793a\u4f8b\u3002\u793a\u4f8b\u4ee5 Web \u524d\u7aef &#043; Node.js \u540e\u7aef\u4e3a\u4e3b\u7ebf&#xff0c;\u540c\u65f6\u517c\u987e\u684c\u9762\u7aef&#xff08;Electron \/ VS Code \u6269\u5c55&#xff09;\u7684\u5dee\u5f02\u70b9\u3002<\/p>\n<hr \/>\n<h3>\u6b63\u6587<\/h3>\n<h4>\u4e00\u3001\u4ea7\u7269\u7c7b\u578b\u8bc6\u522b&#xff1a;\u4e00\u5207\u64cd\u4f5c\u7684\u524d\u63d0<\/h4>\n<p>\u5728\u51b3\u5b9a&#034;\u600e\u4e48\u6253\u5f00&#034;\u4e4b\u524d&#xff0c;\u5fc5\u987b\u5148\u5224\u65ad&#034;\u8fd9\u662f\u4ec0\u4e48&#034;\u3002\u4ea7\u7269\u533a\u901a\u5e38\u9700\u8981\u6839\u636e\u6587\u4ef6\u6269\u5c55\u540d\u6216 MIME \u7c7b\u578b&#xff0c;\u9009\u62e9\u4e0d\u540c\u7684\u5904\u7406\u7b56\u7565&#xff1a;<\/p>\n<table>\n<tr>\u7c7b\u578b\u5178\u578b\u6269\u5c55\u540d\u9ed8\u8ba4\u64cd\u4f5c<\/tr>\n<tbody>\n<tr>\n<td>\u6587\u672c\/\u4ee3\u7801<\/td>\n<td>.txt .md .json .js .py<\/td>\n<td>\u5185\u8054\u9884\u89c8&#xff08;\u9ad8\u4eae&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u56fe\u7247<\/td>\n<td>.png .jpg .svg .webp<\/td>\n<td>\u5185\u8054\u9884\u89c8&#xff08;\u56fe\u7247\u6e32\u67d3&#xff09;<\/td>\n<\/tr>\n<tr>\n<td>\u97f3\u89c6\u9891<\/td>\n<td>.mp3 .mp4 .webm<\/td>\n<td>\u5185\u8054\u64ad\u653e\u5668<\/td>\n<\/tr>\n<tr>\n<td>PDF<\/td>\n<td>.pdf<\/td>\n<td>\u5185\u5d4c iframe \u6216 PDF \u67e5\u770b\u5668<\/td>\n<\/tr>\n<tr>\n<td>\u538b\u7f29\u5305<\/td>\n<td>.zip .tar.gz<\/td>\n<td>\u4ec5\u4e0b\u8f7d<\/td>\n<\/tr>\n<tr>\n<td>\u4e8c\u8fdb\u5236\/\u53ef\u6267\u884c<\/td>\n<td>.exe .so .bin<\/td>\n<td>\u4ec5\u4e0b\u8f7d &#043; \u5b9a\u4f4d<\/td>\n<\/tr>\n<tr>\n<td>\u8d85\u5927\u6587\u672c<\/td>\n<td>\u4efb\u610f\u6587\u672c &gt; \u9608\u503c<\/td>\n<td>\u622a\u65ad\u9884\u89c8 &#043; \u63d0\u793a\u4e0b\u8f7d<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u4e0b\u9762\u662f\u4e00\u4e2a\u5b9e\u7528\u7684\u7c7b\u578b\u5224\u5b9a\u51fd\u6570&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ artifact-type.js<\/span><br \/>\n<span class=\"token comment\">\/\/ \u6839\u636e\u6587\u4ef6\u540d\u548c\u5927\u5c0f\u5224\u65ad\u4ea7\u7269\u7684\u9884\u89c8\u7b56\u7565<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> <span class=\"token constant\">TEXT_EXTS<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;txt&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;md&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;json&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;js&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;ts&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;py&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;java&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;c&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;cpp&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;html&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;css&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;xml&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;yaml&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;yml&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;log&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> <span class=\"token constant\">IMAGE_EXTS<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;png&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;jpg&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;jpeg&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;gif&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;svg&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;webp&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;bmp&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;ico&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> <span class=\"token constant\">MEDIA_EXTS<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;mp3&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;wav&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;mp4&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;webm&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;ogg&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> <span class=\"token constant\">ARCHIVE_EXTS<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">[<\/span><span class=\"token string\">&#039;zip&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;tar&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;gz&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;7z&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;rar&#039;<\/span><span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u9884\u89c8\u5927\u5c0f\u9608\u503c&#xff1a;\u8d85\u8fc7 2MB \u7684\u6587\u672c\u4e0d\u505a\u5b8c\u6574\u5185\u8054\u9884\u89c8<\/span><br \/>\n<span class=\"token keyword\">const<\/span> <span class=\"token constant\">TEXT_PREVIEW_LIMIT<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token number\">2<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">1024<\/span> <span class=\"token operator\">*<\/span> <span class=\"token number\">1024<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token comment\">\/**<br \/>\n * \u83b7\u53d6\u4ea7\u7269\u9884\u89c8\u7b56\u7565<br \/>\n * &#064;param {string} fileName \u4ea7\u7269\u6587\u4ef6\u540d<br \/>\n * &#064;param {number} size \u6587\u4ef6\u5b57\u8282\u6570<br \/>\n * &#064;returns {{ kind: string, previewable: boolean, reason?: string }}<br \/>\n *\/<\/span><br \/>\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">resolveArtifactStrategy<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">fileName<span class=\"token punctuation\">,<\/span> size<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> ext <span class=\"token operator\">&#061;<\/span> fileName<span class=\"token punctuation\">.<\/span><span class=\"token function\">split<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;.&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">pop<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toLowerCase<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token constant\">TEXT_EXTS<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">includes<\/span><span class=\"token punctuation\">(<\/span>ext<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>size <span class=\"token operator\">&gt;<\/span> <span class=\"token constant\">TEXT_PREVIEW_LIMIT<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">kind<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;text&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">previewable<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">reason<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;\u6587\u4ef6\u8fc7\u5927&#xff0c;\u5efa\u8bae\u4e0b\u8f7d\u540e\u67e5\u770b&#039;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">kind<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;text&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">previewable<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><\/p>\n<p>  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token constant\">IMAGE_EXTS<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">includes<\/span><span class=\"token punctuation\">(<\/span>ext<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/ \u56fe\u7247\u4e00\u822c\u53ef\u4ee5\u76f4\u63a5\u9884\u89c8&#xff0c;\u8d85\u5927\u56fe\u7247\u4ea4\u7ed9\u6d4f\u89c8\u5668\u5904\u7406<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">kind<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;image&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">previewable<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><\/p>\n<p>  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token constant\">MEDIA_EXTS<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">includes<\/span><span class=\"token punctuation\">(<\/span>ext<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">kind<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;media&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">previewable<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><\/p>\n<p>  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>ext <span class=\"token operator\">&#061;&#061;&#061;<\/span> <span class=\"token string\">&#039;pdf&#039;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">kind<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;pdf&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">previewable<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">true<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><\/p>\n<p>  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token constant\">ARCHIVE_EXTS<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">includes<\/span><span class=\"token punctuation\">(<\/span>ext<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">kind<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;archive&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">previewable<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">reason<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;\u538b\u7f29\u5305\u9700\u4e0b\u8f7d\u540e\u89e3\u538b&#039;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><\/p>\n<p>  <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">kind<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;binary&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">previewable<\/span><span class=\"token operator\">:<\/span> <span class=\"token boolean\">false<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">reason<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;\u4e8c\u8fdb\u5236\u6587\u4ef6\u4e0d\u652f\u6301\u9884\u89c8&#039;<\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>module<span class=\"token punctuation\">.<\/span>exports <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span> resolveArtifactStrategy <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>\u8981\u70b9&#xff1a;\u7c7b\u578b\u8bc6\u522b\u8981\u540c\u65f6\u8003\u8651\u6269\u5c55\u540d\u548c\u6587\u4ef6\u5927\u5c0f\u3002\u53ea\u770b\u6269\u5c55\u540d\u4f1a\u5bfc\u81f4\u4e00\u4e2a 500MB \u7684 .log \u6587\u4ef6\u628a\u6d4f\u89c8\u5668\u5361\u6b7b\u3002<\/p>\n<hr \/>\n<h4>\u4e8c\u3001\u53f3\u4fa7\u4ea7\u7269\u533a\u7684\u9884\u89c8\u5b9e\u73b0<\/h4>\n<h5>2.1 \u5e03\u5c40\u4e0e\u6570\u636e\u6d41<\/h5>\n<p>\u5178\u578b\u7684\u53f3\u4fa7\u4ea7\u7269\u533a\u91c7\u7528&#034;\u5217\u8868 &#043; \u8be6\u60c5&#034;\u7684\u4e24\u680f\u7ed3\u6784\u3002\u5de6\u4fa7\u662f\u4ea7\u7269\u5217\u8868&#xff0c;\u53f3\u4fa7\u662f\u9009\u4e2d\u4ea7\u7269\u7684\u9884\u89c8\u9762\u677f\u3002\u6570\u636e\u6d41\u5982\u4e0b&#xff1a;<\/p>\n<p>\u540e\u7aef\u4ea7\u7269\u5143\u6570\u636e API \u2192 \u524d\u7aef\u4ea7\u7269\u5217\u8868 \u2192 \u7528\u6237\u70b9\u51fb \u2192 \u6309\u7c7b\u578b\u8bf7\u6c42\u5185\u5bb9 \u2192 \u6e32\u67d3\u9884\u89c8<\/p>\n<h5>2.2 \u6587\u672c\u9884\u89c8&#xff1a;\u6309\u9700\u52a0\u8f7d &#043; \u622a\u65ad<\/h5>\n<p>\u6587\u672c\u9884\u89c8\u4e0d\u5efa\u8bae\u4e00\u6b21\u6027\u62c9\u53d6\u5168\u91cf\u5185\u5bb9&#xff0c;\u800c\u5e94\u652f\u6301\u8303\u56f4\u8bfb\u53d6\u6216\u622a\u65ad\u8bfb\u53d6\u3002\u4e0b\u9762\u662f\u4e00\u4e2a\u540e\u7aef\u8303\u56f4\u8bfb\u53d6\u63a5\u53e3&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ server.js&#xff08;Express \u793a\u4f8b&#xff09;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> express <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;express&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> fs <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;fs&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> path <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;path&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> <span class=\"token punctuation\">{<\/span> resolveArtifactStrategy <span class=\"token punctuation\">}<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;.\/artifact-type&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">const<\/span> app <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">express<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> <span class=\"token constant\">ARTIFACT_ROOT<\/span> <span class=\"token operator\">&#061;<\/span> path<span class=\"token punctuation\">.<\/span><span class=\"token function\">resolve<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;.\/artifacts&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u5b89\u5168\u6821\u9a8c&#xff1a;\u9632\u6b62\u8def\u5f84\u7a7f\u8d8a<\/span><br \/>\n<span class=\"token keyword\">function<\/span> <span class=\"token function\">safeResolve<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">relPath<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> abs <span class=\"token operator\">&#061;<\/span> path<span class=\"token punctuation\">.<\/span><span class=\"token function\">resolve<\/span><span class=\"token punctuation\">(<\/span><span class=\"token constant\">ARTIFACT_ROOT<\/span><span class=\"token punctuation\">,<\/span> relPath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>abs<span class=\"token punctuation\">.<\/span><span class=\"token function\">startsWith<\/span><span class=\"token punctuation\">(<\/span><span class=\"token constant\">ARTIFACT_ROOT<\/span> <span class=\"token operator\">&#043;<\/span> path<span class=\"token punctuation\">.<\/span>sep<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">Error<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;\u975e\u6cd5\u8def\u5f84&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n  <span class=\"token keyword\">return<\/span> abs<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u83b7\u53d6\u4ea7\u7269\u5217\u8868&#xff08;\u542b\u7c7b\u578b\u7b56\u7565&#xff09;<\/span><br \/>\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;\/api\/artifacts&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">req<span class=\"token punctuation\">,<\/span> res<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> files <span class=\"token operator\">&#061;<\/span> fs<span class=\"token punctuation\">.<\/span><span class=\"token function\">readdirSync<\/span><span class=\"token punctuation\">(<\/span><span class=\"token constant\">ARTIFACT_ROOT<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> list <span class=\"token operator\">&#061;<\/span> files<span class=\"token punctuation\">.<\/span><span class=\"token function\">map<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">name<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> stat <span class=\"token operator\">&#061;<\/span> fs<span class=\"token punctuation\">.<\/span><span class=\"token function\">statSync<\/span><span class=\"token punctuation\">(<\/span>path<span class=\"token punctuation\">.<\/span><span class=\"token function\">join<\/span><span class=\"token punctuation\">(<\/span><span class=\"token constant\">ARTIFACT_ROOT<\/span><span class=\"token punctuation\">,<\/span> name<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n      name<span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token literal-property property\">size<\/span><span class=\"token operator\">:<\/span> stat<span class=\"token punctuation\">.<\/span>size<span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token literal-property property\">mtime<\/span><span class=\"token operator\">:<\/span> stat<span class=\"token punctuation\">.<\/span>mtimeMs<span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token literal-property property\">strategy<\/span><span class=\"token operator\">:<\/span> <span class=\"token function\">resolveArtifactStrategy<\/span><span class=\"token punctuation\">(<\/span>name<span class=\"token punctuation\">,<\/span> stat<span class=\"token punctuation\">.<\/span>size<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  res<span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span>list<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token comment\">\/\/ \u9884\u89c8\u63a5\u53e3&#xff1a;\u652f\u6301 ?maxBytes \u622a\u65ad<\/span><br \/>\napp<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;\/api\/artifacts\/:name\/preview&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">req<span class=\"token punctuation\">,<\/span> res<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> filePath <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">safeResolve<\/span><span class=\"token punctuation\">(<\/span>req<span class=\"token punctuation\">.<\/span>params<span class=\"token punctuation\">.<\/span>name<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> maxBytes <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">parseInt<\/span><span class=\"token punctuation\">(<\/span>req<span class=\"token punctuation\">.<\/span>query<span class=\"token punctuation\">.<\/span>maxBytes <span class=\"token operator\">||<\/span> <span class=\"token string\">&#039;200000&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">10<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>  <span class=\"token keyword\">const<\/span> stat <span class=\"token operator\">&#061;<\/span> fs<span class=\"token punctuation\">.<\/span><span class=\"token function\">statSync<\/span><span class=\"token punctuation\">(<\/span>filePath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> strategy <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">resolveArtifactStrategy<\/span><span class=\"token punctuation\">(<\/span>req<span class=\"token punctuation\">.<\/span>params<span class=\"token punctuation\">.<\/span>name<span class=\"token punctuation\">,<\/span> stat<span class=\"token punctuation\">.<\/span>size<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>strategy<span class=\"token punctuation\">.<\/span>previewable<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">return<\/span> res<span class=\"token punctuation\">.<\/span><span class=\"token function\">status<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">415<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">error<\/span><span class=\"token operator\">:<\/span> strategy<span class=\"token punctuation\">.<\/span>reason <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><\/p>\n<p>  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>strategy<span class=\"token punctuation\">.<\/span>kind <span class=\"token operator\">&#061;&#061;&#061;<\/span> <span class=\"token string\">&#039;text&#039;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> fd <span class=\"token operator\">&#061;<\/span> fs<span class=\"token punctuation\">.<\/span><span class=\"token function\">openSync<\/span><span class=\"token punctuation\">(<\/span>filePath<span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;r&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> buf <span class=\"token operator\">&#061;<\/span> Buffer<span class=\"token punctuation\">.<\/span><span class=\"token function\">alloc<\/span><span class=\"token punctuation\">(<\/span>Math<span class=\"token punctuation\">.<\/span><span class=\"token function\">min<\/span><span class=\"token punctuation\">(<\/span>maxBytes<span class=\"token punctuation\">,<\/span> stat<span class=\"token punctuation\">.<\/span>size<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    fs<span class=\"token punctuation\">.<\/span><span class=\"token function\">readSync<\/span><span class=\"token punctuation\">(<\/span>fd<span class=\"token punctuation\">,<\/span> buf<span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">,<\/span> buf<span class=\"token punctuation\">.<\/span>length<span class=\"token punctuation\">,<\/span> <span class=\"token number\">0<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    fs<span class=\"token punctuation\">.<\/span><span class=\"token function\">closeSync<\/span><span class=\"token punctuation\">(<\/span>fd<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    <span class=\"token keyword\">return<\/span> res<span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token literal-property property\">kind<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;text&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token literal-property property\">truncated<\/span><span class=\"token operator\">:<\/span> stat<span class=\"token punctuation\">.<\/span>size <span class=\"token operator\">&gt;<\/span> maxBytes<span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token literal-property property\">totalSize<\/span><span class=\"token operator\">:<\/span> stat<span class=\"token punctuation\">.<\/span>size<span class=\"token punctuation\">,<\/span><br \/>\n      <span class=\"token literal-property property\">content<\/span><span class=\"token operator\">:<\/span> buf<span class=\"token punctuation\">.<\/span><span class=\"token function\">toString<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;utf8&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><\/p>\n<p>  <span class=\"token comment\">\/\/ \u56fe\u7247 \/ \u5a92\u4f53 \/ PDF \u76f4\u63a5\u6d41\u5f0f\u8fd4\u56de<\/span><br \/>\n  res<span class=\"token punctuation\">.<\/span><span class=\"token function\">setHeader<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;Content-Type&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token function\">guessMime<\/span><span class=\"token punctuation\">(<\/span>req<span class=\"token punctuation\">.<\/span>params<span class=\"token punctuation\">.<\/span>name<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  fs<span class=\"token punctuation\">.<\/span><span class=\"token function\">createReadStream<\/span><span class=\"token punctuation\">(<\/span>filePath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">pipe<\/span><span class=\"token punctuation\">(<\/span>res<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">function<\/span> <span class=\"token function\">guessMime<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">name<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> ext <span class=\"token operator\">&#061;<\/span> name<span class=\"token punctuation\">.<\/span><span class=\"token function\">split<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;.&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">pop<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">toLowerCase<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> map <span class=\"token operator\">&#061;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token literal-property property\">png<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;image\/png&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">jpg<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;image\/jpeg&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">jpeg<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;image\/jpeg&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token literal-property property\">svg<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;image\/svg&#043;xml&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">webp<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;image\/webp&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token literal-property property\">pdf<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;application\/pdf&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">mp4<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;video\/mp4&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token literal-property property\">mp3<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;audio\/mpeg&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">return<\/span> map<span class=\"token punctuation\">[<\/span>ext<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">||<\/span> <span class=\"token string\">&#039;application\/octet-stream&#039;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>app<span class=\"token punctuation\">.<\/span><span class=\"token function\">listen<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">3000<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;artifact server on :3000&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>\u524d\u7aef\u9884\u89c8\u7ec4\u4ef6\u6839\u636e kind \u5206\u652f\u6e32\u67d3&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ preview-panel.js&#xff08;\u6d4f\u89c8\u5668\u7aef&#xff0c;\u65e0\u6846\u67b6\u4f9d\u8d56&#xff09;<\/span><br \/>\n<span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">renderPreview<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">artifactName<span class=\"token punctuation\">,<\/span> container<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> res <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">await<\/span> <span class=\"token function\">fetch<\/span><span class=\"token punctuation\">(<\/span><span class=\"token template-string\"><span class=\"token template-punctuation string\">&#096;<\/span><span class=\"token string\">\/api\/artifacts\/<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token function\">encodeURIComponent<\/span><span class=\"token punctuation\">(<\/span>artifactName<span class=\"token punctuation\">)<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">\/preview<\/span><span class=\"token template-punctuation string\">&#096;<\/span><\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>res<span class=\"token punctuation\">.<\/span>ok<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> err <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">await<\/span> res<span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    container<span class=\"token punctuation\">.<\/span>innerHTML <span class=\"token operator\">&#061;<\/span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">&#096;<\/span><span class=\"token string\">&lt;p class&#061;&#034;preview-error&#034;&gt;\u65e0\u6cd5\u9884\u89c8&#xff1a;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>err<span class=\"token punctuation\">.<\/span>error<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&lt;\/p&gt;<\/span><span class=\"token template-punctuation string\">&#096;<\/span><\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><\/p>\n<p>  <span class=\"token keyword\">const<\/span> contentType <span class=\"token operator\">&#061;<\/span> res<span class=\"token punctuation\">.<\/span>headers<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;content-type&#039;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">||<\/span> <span class=\"token string\">&#039;&#039;<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>contentType<span class=\"token punctuation\">.<\/span><span class=\"token function\">includes<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;application\/json&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> data <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">await<\/span> res<span class=\"token punctuation\">.<\/span><span class=\"token function\">json<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token comment\">\/\/ \u6587\u672c\u9884\u89c8&#xff1a;\u7528 &lt;pre&gt; \u5c55\u793a&#xff0c;\u622a\u65ad\u65f6\u7ed9\u51fa\u63d0\u793a<\/span><br \/>\n    container<span class=\"token punctuation\">.<\/span>innerHTML <span class=\"token operator\">&#061;<\/span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">&#096;<\/span><span class=\"token string\"><br \/>\n      <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>data<span class=\"token punctuation\">.<\/span>truncated <span class=\"token operator\">?<\/span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">&#096;<\/span><span class=\"token string\">&lt;p class&#061;&#034;hint&#034;&gt;\u4ec5\u663e\u793a\u524d <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>data<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">.<\/span>length<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\"> \u5b57\u8282&#xff08;\u5171 <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>data<span class=\"token punctuation\">.<\/span>totalSize<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\"> \u5b57\u8282&#xff09;&lt;\/p&gt;<\/span><span class=\"token template-punctuation string\">&#096;<\/span><\/span> <span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;&#039;<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\"><br \/>\n      &lt;pre class&#061;&#034;text-preview&#034;&gt;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token function\">escapeHtml<\/span><span class=\"token punctuation\">(<\/span>data<span class=\"token punctuation\">.<\/span>content<span class=\"token punctuation\">)<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&lt;\/pre&gt;<\/span><span class=\"token template-punctuation string\">&#096;<\/span><\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><\/p>\n<p>  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>contentType<span class=\"token punctuation\">.<\/span><span class=\"token function\">startsWith<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;image\/&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    container<span class=\"token punctuation\">.<\/span>innerHTML <span class=\"token operator\">&#061;<\/span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">&#096;<\/span><span class=\"token string\">&lt;img src&#061;&#034;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token constant\">URL<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">createObjectURL<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">await<\/span> res<span class=\"token punctuation\">.<\/span><span class=\"token function\">blob<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#034; alt&#061;&#034;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>artifactName<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#034; \/&gt;<\/span><span class=\"token template-punctuation string\">&#096;<\/span><\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><\/p>\n<p>  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>contentType <span class=\"token operator\">&#061;&#061;&#061;<\/span> <span class=\"token string\">&#039;application\/pdf&#039;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> url <span class=\"token operator\">&#061;<\/span> <span class=\"token constant\">URL<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">createObjectURL<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">await<\/span> res<span class=\"token punctuation\">.<\/span><span class=\"token function\">blob<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    container<span class=\"token punctuation\">.<\/span>innerHTML <span class=\"token operator\">&#061;<\/span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">&#096;<\/span><span class=\"token string\">&lt;iframe src&#061;&#034;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>url<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#034; class&#061;&#034;pdf-preview&#034;&gt;&lt;\/iframe&gt;<\/span><span class=\"token template-punctuation string\">&#096;<\/span><\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><\/p>\n<p>  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>contentType<span class=\"token punctuation\">.<\/span><span class=\"token function\">startsWith<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;video\/&#039;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">||<\/span> contentType<span class=\"token punctuation\">.<\/span><span class=\"token function\">startsWith<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;audio\/&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> tag <span class=\"token operator\">&#061;<\/span> contentType<span class=\"token punctuation\">.<\/span><span class=\"token function\">startsWith<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;video\/&#039;<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">?<\/span> <span class=\"token string\">&#039;video&#039;<\/span> <span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;audio&#039;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> url <span class=\"token operator\">&#061;<\/span> <span class=\"token constant\">URL<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">createObjectURL<\/span><span class=\"token punctuation\">(<\/span><span class=\"token keyword\">await<\/span> res<span class=\"token punctuation\">.<\/span><span class=\"token function\">blob<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    container<span class=\"token punctuation\">.<\/span>innerHTML <span class=\"token operator\">&#061;<\/span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">&#096;<\/span><span class=\"token string\">&lt;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>tag<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\"> src&#061;&#034;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>url<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#034; controls&gt;&lt;\/<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>tag<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&gt;<\/span><span class=\"token template-punctuation string\">&#096;<\/span><\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><\/p>\n<p>  container<span class=\"token punctuation\">.<\/span>innerHTML <span class=\"token operator\">&#061;<\/span> <span class=\"token string\">&#039;&lt;p class&#061;&#034;hint&#034;&gt;\u8be5\u7c7b\u578b\u6682\u4e0d\u652f\u6301\u5185\u8054\u9884\u89c8&#xff0c;\u8bf7\u4e0b\u8f7d\u67e5\u770b\u3002&lt;\/p&gt;&#039;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p><span class=\"token keyword\">function<\/span> <span class=\"token function\">escapeHtml<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">str<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">return<\/span> str<span class=\"token punctuation\">.<\/span><span class=\"token function\">replace<\/span><span class=\"token punctuation\">(<\/span><span class=\"token regex\"><span class=\"token regex-delimiter\">\/<\/span><span class=\"token regex-source language-regex\">[&amp;&lt;&gt;&#034;&#039;]<\/span><span class=\"token regex-delimiter\">\/<\/span><span class=\"token regex-flags\">g<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">c<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token string-property property\">&#039;&amp;&#039;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;&amp;amp;&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string-property property\">&#039;&lt;&#039;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;&amp;lt;&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string-property property\">&#039;&gt;&#039;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;&amp;gt;&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string-property property\">&#039;&#034;&#039;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;&amp;quot;&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string-property property\">&#034;&#039;&#034;<\/span><span class=\"token operator\">:<\/span> <span class=\"token string\">&#039;&amp;#39;&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">[<\/span>c<span class=\"token punctuation\">]<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u8981\u70b9&#xff1a;<\/p>\n<ul>\n<li>\u6587\u672c\u9884\u89c8\u52a1\u5fc5\u505a\u622a\u65ad\u4e0eHTML \u8f6c\u4e49&#xff0c;\u524d\u8005\u9632\u6b62\u5361\u987f&#xff0c;\u540e\u8005\u9632\u6b62 XSS\u3002<\/li>\n<li>\u56fe\u7247\u3001PDF\u3001\u97f3\u89c6\u9891\u7528 Blob URL \u6e32\u67d3&#xff0c;\u907f\u514d\u76f4\u63a5\u66b4\u9732\u540e\u7aef\u8def\u5f84\u3002<\/li>\n<\/ul>\n<hr \/>\n<h4>\u4e09\u3001\u4e0b\u8f7d\u4ea7\u7269&#xff1a;\u4ece\u94fe\u63a5\u5230\u843d\u76d8<\/h4>\n<h5>3.1 \u6d4f\u89c8\u5668\u4e0b\u8f7d\u7684\u4e24\u79cd\u65b9\u5f0f<\/h5>\n<p>\u65b9\u5f0f\u4e00&#xff1a;&lt;a download&gt; \u76f4\u63a5\u4e0b\u8f7d<\/p>\n<p><span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;<\/span>a<\/span> <span class=\"token attr-name\">href<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>\/api\/artifacts\/report.pdf\/download<span class=\"token punctuation\">&#034;<\/span><\/span> <span class=\"token attr-name\">download<\/span><span class=\"token attr-value\"><span class=\"token punctuation attr-equals\">&#061;<\/span><span class=\"token punctuation\">&#034;<\/span>report.pdf<span class=\"token punctuation\">&#034;<\/span><\/span><span class=\"token punctuation\">&gt;<\/span><\/span>\u4e0b\u8f7d<span class=\"token tag\"><span class=\"token tag\"><span class=\"token punctuation\">&lt;\/<\/span>a<\/span><span class=\"token punctuation\">&gt;<\/span><\/span><\/p>\n<p>\u540e\u7aef\u9700\u8981\u8bbe\u7f6e\u6b63\u786e\u7684\u54cd\u5e94\u5934&#xff1a;<\/p>\n<p>app<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;\/api\/artifacts\/:name\/download&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">req<span class=\"token punctuation\">,<\/span> res<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> filePath <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">safeResolve<\/span><span class=\"token punctuation\">(<\/span>req<span class=\"token punctuation\">.<\/span>params<span class=\"token punctuation\">.<\/span>name<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> fileName <span class=\"token operator\">&#061;<\/span> path<span class=\"token punctuation\">.<\/span><span class=\"token function\">basename<\/span><span class=\"token punctuation\">(<\/span>filePath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>  res<span class=\"token punctuation\">.<\/span><span class=\"token function\">setHeader<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;Content-Disposition&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">&#096;<\/span><span class=\"token string\">attachment; filename&#061;&#034;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token function\">encodeURIComponent<\/span><span class=\"token punctuation\">(<\/span>fileName<span class=\"token punctuation\">)<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#034;<\/span><span class=\"token template-punctuation string\">&#096;<\/span><\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  res<span class=\"token punctuation\">.<\/span><span class=\"token function\">setHeader<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;Content-Type&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;application\/octet-stream&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  fs<span class=\"token punctuation\">.<\/span><span class=\"token function\">createReadStream<\/span><span class=\"token punctuation\">(<\/span>filePath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">pipe<\/span><span class=\"token punctuation\">(<\/span>res<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>\u65b9\u5f0f\u4e8c&#xff1a;fetch &#043; Blob \u4e0b\u8f7d&#xff08;\u9002\u5408\u9700\u8981\u9274\u6743\u7684\u573a\u666f&#xff09;<\/p>\n<p><span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">downloadArtifact<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">name<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> res <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">await<\/span> <span class=\"token function\">fetch<\/span><span class=\"token punctuation\">(<\/span><span class=\"token template-string\"><span class=\"token template-punctuation string\">&#096;<\/span><span class=\"token string\">\/api\/artifacts\/<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token function\">encodeURIComponent<\/span><span class=\"token punctuation\">(<\/span>name<span class=\"token punctuation\">)<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">\/download<\/span><span class=\"token template-punctuation string\">&#096;<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token literal-property property\">headers<\/span><span class=\"token operator\">:<\/span> <span class=\"token punctuation\">{<\/span> <span class=\"token literal-property property\">Authorization<\/span><span class=\"token operator\">:<\/span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">&#096;<\/span><span class=\"token string\">Bearer <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span><span class=\"token function\">getToken<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token template-punctuation string\">&#096;<\/span><\/span> <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">,<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>res<span class=\"token punctuation\">.<\/span>ok<span class=\"token punctuation\">)<\/span> <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">Error<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;\u4e0b\u8f7d\u5931\u8d25&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>  <span class=\"token keyword\">const<\/span> blob <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">await<\/span> res<span class=\"token punctuation\">.<\/span><span class=\"token function\">blob<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> url <span class=\"token operator\">&#061;<\/span> <span class=\"token constant\">URL<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">createObjectURL<\/span><span class=\"token punctuation\">(<\/span>blob<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> a <span class=\"token operator\">&#061;<\/span> document<span class=\"token punctuation\">.<\/span><span class=\"token function\">createElement<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;a&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  a<span class=\"token punctuation\">.<\/span>href <span class=\"token operator\">&#061;<\/span> url<span class=\"token punctuation\">;<\/span><br \/>\n  a<span class=\"token punctuation\">.<\/span>download <span class=\"token operator\">&#061;<\/span> name<span class=\"token punctuation\">;<\/span><br \/>\n  document<span class=\"token punctuation\">.<\/span>body<span class=\"token punctuation\">.<\/span><span class=\"token function\">appendChild<\/span><span class=\"token punctuation\">(<\/span>a<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  a<span class=\"token punctuation\">.<\/span><span class=\"token function\">click<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  a<span class=\"token punctuation\">.<\/span><span class=\"token function\">remove<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token comment\">\/\/ \u91ca\u653e\u5185\u5b58<\/span><br \/>\n  <span class=\"token function\">setTimeout<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token constant\">URL<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">revokeObjectURL<\/span><span class=\"token punctuation\">(<\/span>url<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token number\">1000<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h5>3.2 \u5927\u6587\u4ef6\u4e0b\u8f7d&#xff1a;\u6d41\u5f0f\u4e0e\u65ad\u70b9\u7eed\u4f20<\/h5>\n<p>\u5bf9\u4e8e\u5927\u4ea7\u7269&#xff0c;\u5e94\u652f\u6301 Range \u8bf7\u6c42\u5b9e\u73b0\u65ad\u70b9\u7eed\u4f20&#xff1a;<\/p>\n<p>app<span class=\"token punctuation\">.<\/span><span class=\"token function\">get<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;\/api\/artifacts\/:name\/download&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">req<span class=\"token punctuation\">,<\/span> res<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> filePath <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">safeResolve<\/span><span class=\"token punctuation\">(<\/span>req<span class=\"token punctuation\">.<\/span>params<span class=\"token punctuation\">.<\/span>name<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> stat <span class=\"token operator\">&#061;<\/span> fs<span class=\"token punctuation\">.<\/span><span class=\"token function\">statSync<\/span><span class=\"token punctuation\">(<\/span>filePath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> range <span class=\"token operator\">&#061;<\/span> req<span class=\"token punctuation\">.<\/span>headers<span class=\"token punctuation\">.<\/span>range<span class=\"token punctuation\">;<\/span><\/p>\n<p>  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span>range<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> <span class=\"token punctuation\">[<\/span>startStr<span class=\"token punctuation\">,<\/span> endStr<span class=\"token punctuation\">]<\/span> <span class=\"token operator\">&#061;<\/span> range<span class=\"token punctuation\">.<\/span><span class=\"token function\">replace<\/span><span class=\"token punctuation\">(<\/span><span class=\"token regex\"><span class=\"token regex-delimiter\">\/<\/span><span class=\"token regex-source language-regex\">bytes&#061;<\/span><span class=\"token regex-delimiter\">\/<\/span><\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">split<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;-&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> start <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">parseInt<\/span><span class=\"token punctuation\">(<\/span>startStr<span class=\"token punctuation\">,<\/span> <span class=\"token number\">10<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> end <span class=\"token operator\">&#061;<\/span> endStr <span class=\"token operator\">?<\/span> <span class=\"token function\">parseInt<\/span><span class=\"token punctuation\">(<\/span>endStr<span class=\"token punctuation\">,<\/span> <span class=\"token number\">10<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">:<\/span> stat<span class=\"token punctuation\">.<\/span>size <span class=\"token operator\">&#8211;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>    res<span class=\"token punctuation\">.<\/span><span class=\"token function\">status<\/span><span class=\"token punctuation\">(<\/span><span class=\"token number\">206<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    res<span class=\"token punctuation\">.<\/span><span class=\"token function\">setHeader<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;Content-Range&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token template-string\"><span class=\"token template-punctuation string\">&#096;<\/span><span class=\"token string\">bytes <\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>start<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">&#8211;<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>end<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token string\">\/<\/span><span class=\"token interpolation\"><span class=\"token interpolation-punctuation punctuation\">${<\/span>stat<span class=\"token punctuation\">.<\/span>size<span class=\"token interpolation-punctuation punctuation\">}<\/span><\/span><span class=\"token template-punctuation string\">&#096;<\/span><\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    res<span class=\"token punctuation\">.<\/span><span class=\"token function\">setHeader<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;Accept-Ranges&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;bytes&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    res<span class=\"token punctuation\">.<\/span><span class=\"token function\">setHeader<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;Content-Length&#039;<\/span><span class=\"token punctuation\">,<\/span> end <span class=\"token operator\">&#8211;<\/span> start <span class=\"token operator\">&#043;<\/span> <span class=\"token number\">1<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    fs<span class=\"token punctuation\">.<\/span><span class=\"token function\">createReadStream<\/span><span class=\"token punctuation\">(<\/span>filePath<span class=\"token punctuation\">,<\/span> <span class=\"token punctuation\">{<\/span> start<span class=\"token punctuation\">,<\/span> end <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">pipe<\/span><span class=\"token punctuation\">(<\/span>res<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">else<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    res<span class=\"token punctuation\">.<\/span><span class=\"token function\">setHeader<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;Content-Length&#039;<\/span><span class=\"token punctuation\">,<\/span> stat<span class=\"token punctuation\">.<\/span>size<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    res<span class=\"token punctuation\">.<\/span><span class=\"token function\">setHeader<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;Accept-Ranges&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token string\">&#039;bytes&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    fs<span class=\"token punctuation\">.<\/span><span class=\"token function\">createReadStream<\/span><span class=\"token punctuation\">(<\/span>filePath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">pipe<\/span><span class=\"token punctuation\">(<\/span>res<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>\u8981\u70b9&#xff1a;\u4e0b\u8f7d\u63a5\u53e3\u8981\u533a\u5206&#034;\u9884\u89c8\u7528\u7684\u6d41&#034;\u548c&#034;\u4e0b\u8f7d\u7528\u7684\u6d41&#034;&#xff0c;\u540e\u8005\u5fc5\u987b\u5e26 Content-Disposition: attachment&#xff0c;\u5426\u5219\u6d4f\u89c8\u5668\u53ef\u80fd\u76f4\u63a5\u6253\u5f00\u800c\u975e\u4fdd\u5b58\u3002<\/p>\n<hr \/>\n<h4>\u56db\u3001\u5b9a\u4f4d\u5230\u672c\u5730\u6587\u4ef6&#xff1a;\u8def\u5f84\u6620\u5c04\u4e0e\u7cfb\u7edf\u8c03\u7528<\/h4>\n<p>&#034;\u5b9a\u4f4d&#034;\u529f\u80fd\u5728\u684c\u9762\u7aef&#xff08;Electron\u3001VS Code \u6269\u5c55&#xff09;\u5f88\u5e38\u89c1&#xff0c;\u6838\u5fc3\u662f\u628a\u4ea7\u7269 ID \u6620\u5c04\u4e3a\u672c\u5730\u7edd\u5bf9\u8def\u5f84&#xff0c;\u518d\u8c03\u7528\u7cfb\u7edf API \u6253\u5f00\u6587\u4ef6\u7ba1\u7406\u5668\u5e76\u9009\u4e2d\u8be5\u6587\u4ef6\u3002<\/p>\n<h5>4.1 Electron \u5b9e\u73b0<\/h5>\n<p><span class=\"token comment\">\/\/ main.js&#xff08;Electron \u4e3b\u8fdb\u7a0b&#xff09;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> <span class=\"token punctuation\">{<\/span> ipcMain<span class=\"token punctuation\">,<\/span> shell <span class=\"token punctuation\">}<\/span> <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;electron&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token keyword\">const<\/span> path <span class=\"token operator\">&#061;<\/span> <span class=\"token function\">require<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;path&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>ipcMain<span class=\"token punctuation\">.<\/span><span class=\"token function\">handle<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;artifact:reveal&#039;<\/span><span class=\"token punctuation\">,<\/span> <span class=\"token keyword\">async<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token parameter\">event<span class=\"token punctuation\">,<\/span> artifactName<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> absPath <span class=\"token operator\">&#061;<\/span> path<span class=\"token punctuation\">.<\/span><span class=\"token function\">resolve<\/span><span class=\"token punctuation\">(<\/span><span class=\"token constant\">ARTIFACT_ROOT<\/span><span class=\"token punctuation\">,<\/span> artifactName<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>  <span class=\"token comment\">\/\/ \u5b89\u5168\u6821\u9a8c&#xff1a;\u786e\u4fdd\u8def\u5f84\u5728\u4ea7\u7269\u6839\u76ee\u5f55\u5185<\/span><br \/>\n  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>absPath<span class=\"token punctuation\">.<\/span><span class=\"token function\">startsWith<\/span><span class=\"token punctuation\">(<\/span><span class=\"token constant\">ARTIFACT_ROOT<\/span> <span class=\"token operator\">&#043;<\/span> path<span class=\"token punctuation\">.<\/span>sep<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">throw<\/span> <span class=\"token keyword\">new<\/span> <span class=\"token class-name\">Error<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;\u975e\u6cd5\u8def\u5f84&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><\/p>\n<p>  <span class=\"token comment\">\/\/ showItemInFolder \u4f1a\u6253\u5f00\u6587\u4ef6\u7ba1\u7406\u5668\u5e76\u9009\u4e2d\u8be5\u6587\u4ef6<\/span><br \/>\n  shell<span class=\"token punctuation\">.<\/span><span class=\"token function\">showItemInFolder<\/span><span class=\"token punctuation\">(<\/span>absPath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">return<\/span> absPath<span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>\u6e32\u67d3\u8fdb\u7a0b\u8c03\u7528&#xff1a;<\/p>\n<p><span class=\"token comment\">\/\/ renderer.js<\/span><br \/>\n<span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">revealArtifact<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">name<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">try<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> absPath <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">await<\/span> window<span class=\"token punctuation\">.<\/span>electronAPI<span class=\"token punctuation\">.<\/span><span class=\"token function\">revealArtifact<\/span><span class=\"token punctuation\">(<\/span>name<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    console<span class=\"token punctuation\">.<\/span><span class=\"token function\">log<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;\u5df2\u5b9a\u4f4d\u5230&#xff1a;&#039;<\/span><span class=\"token punctuation\">,<\/span> absPath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span> <span class=\"token keyword\">catch<\/span> <span class=\"token punctuation\">(<\/span>e<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token function\">alert<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;\u5b9a\u4f4d\u5931\u8d25&#xff1a;&#039;<\/span> <span class=\"token operator\">&#043;<\/span> e<span class=\"token punctuation\">.<\/span>message<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h5>4.2 VS Code \u6269\u5c55\u5b9e\u73b0<\/h5>\n<p><span class=\"token comment\">\/\/ extension.ts<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token operator\">*<\/span> <span class=\"token keyword\">as<\/span> vscode <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;vscode&#039;<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token keyword\">import<\/span> <span class=\"token operator\">*<\/span> <span class=\"token keyword\">as<\/span> path <span class=\"token keyword\">from<\/span> <span class=\"token string\">&#039;path&#039;<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p><span class=\"token keyword\">export<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">activate<\/span><span class=\"token punctuation\">(<\/span>context<span class=\"token operator\">:<\/span> vscode<span class=\"token punctuation\">.<\/span>ExtensionContext<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> disposable <span class=\"token operator\">&#061;<\/span> vscode<span class=\"token punctuation\">.<\/span>commands<span class=\"token punctuation\">.<\/span><span class=\"token function\">registerCommand<\/span><span class=\"token punctuation\">(<\/span><br \/>\n    <span class=\"token string\">&#039;artifact.reveal&#039;<\/span><span class=\"token punctuation\">,<\/span><br \/>\n    <span class=\"token keyword\">async<\/span> <span class=\"token punctuation\">(<\/span>artifactName<span class=\"token operator\">:<\/span> <span class=\"token builtin\">string<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token operator\">&#061;&gt;<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n      <span class=\"token keyword\">const<\/span> absPath <span class=\"token operator\">&#061;<\/span> path<span class=\"token punctuation\">.<\/span><span class=\"token function\">join<\/span><span class=\"token punctuation\">(<\/span>context<span class=\"token punctuation\">.<\/span>globalStorageUri<span class=\"token punctuation\">.<\/span>fsPath<span class=\"token punctuation\">,<\/span> artifactName<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n      <span class=\"token keyword\">const<\/span> uri <span class=\"token operator\">&#061;<\/span> vscode<span class=\"token punctuation\">.<\/span>Uri<span class=\"token punctuation\">.<\/span><span class=\"token function\">file<\/span><span class=\"token punctuation\">(<\/span>absPath<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><\/p>\n<p>      <span class=\"token comment\">\/\/ \u5728\u8d44\u6e90\u7ba1\u7406\u5668\u4e2d\u663e\u793a\u5e76\u9009\u4e2d<\/span><br \/>\n      <span class=\"token keyword\">await<\/span> vscode<span class=\"token punctuation\">.<\/span>commands<span class=\"token punctuation\">.<\/span><span class=\"token function\">executeCommand<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;revealInExplorer&#039;<\/span><span class=\"token punctuation\">,<\/span> uri<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token punctuation\">}<\/span><br \/>\n  <span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  context<span class=\"token punctuation\">.<\/span>subscriptions<span class=\"token punctuation\">.<\/span><span class=\"token function\">push<\/span><span class=\"token punctuation\">(<\/span>disposable<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<h5>4.3 Web \u7aef\u7684\u73b0\u5b9e\u7ea6\u675f<\/h5>\n<p>\u7eaf\u6d4f\u89c8\u5668\u73af\u5883\u65e0\u6cd5\u76f4\u63a5\u6253\u5f00\u672c\u5730\u6587\u4ef6\u7ba1\u7406\u5668\u2014\u2014\u8fd9\u662f\u5b89\u5168\u6c99\u7bb1\u7684\u786c\u9650\u5236\u3002Web \u7aef\u53ea\u80fd\u505a\u5230&#xff1a;<\/p>\n<li>\u63d0\u4f9b&#034;\u4e0b\u8f7d&#034;\u8ba9\u7528\u6237\u81ea\u884c\u4fdd\u5b58&#xff1b;<\/li>\n<li>\u82e5\u4ea7\u7269\u6765\u81ea\u7528\u6237\u901a\u8fc7 File System Access API \u9009\u62e9\u7684\u76ee\u5f55&#xff0c;\u53ef\u7528 showSaveFilePicker \u7b49 API \u4fdd\u5b58\u5230\u5df2\u77e5\u4f4d\u7f6e&#xff1a;<\/li>\n<p><span class=\"token comment\">\/\/ \u4ec5\u5728\u652f\u6301 File System Access API \u7684\u6d4f\u89c8\u5668&#xff08;Chromium \u7cfb&#xff09;\u53ef\u7528<\/span><br \/>\n<span class=\"token keyword\">async<\/span> <span class=\"token keyword\">function<\/span> <span class=\"token function\">saveToKnownLocation<\/span><span class=\"token punctuation\">(<\/span><span class=\"token parameter\">blob<span class=\"token punctuation\">,<\/span> suggestedName<\/span><span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n  <span class=\"token keyword\">if<\/span> <span class=\"token punctuation\">(<\/span><span class=\"token operator\">!<\/span>window<span class=\"token punctuation\">.<\/span>showSaveFilePicker<span class=\"token punctuation\">)<\/span> <span class=\"token punctuation\">{<\/span><br \/>\n    <span class=\"token comment\">\/\/ \u964d\u7ea7\u4e3a\u666e\u901a\u4e0b\u8f7d<\/span><br \/>\n    <span class=\"token keyword\">const<\/span> a <span class=\"token operator\">&#061;<\/span> document<span class=\"token punctuation\">.<\/span><span class=\"token function\">createElement<\/span><span class=\"token punctuation\">(<\/span><span class=\"token string\">&#039;a&#039;<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    a<span class=\"token punctuation\">.<\/span>href <span class=\"token operator\">&#061;<\/span> <span class=\"token constant\">URL<\/span><span class=\"token punctuation\">.<\/span><span class=\"token function\">createObjectURL<\/span><span class=\"token punctuation\">(<\/span>blob<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    a<span class=\"token punctuation\">.<\/span>download <span class=\"token operator\">&#061;<\/span> suggestedName<span class=\"token punctuation\">;<\/span><br \/>\n    a<span class=\"token punctuation\">.<\/span><span class=\"token function\">click<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n    <span class=\"token keyword\">return<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token punctuation\">}<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> handle <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">await<\/span> window<span class=\"token punctuation\">.<\/span><span class=\"token function\">showSaveFilePicker<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">{<\/span> suggestedName <span class=\"token punctuation\">}<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">const<\/span> writable <span class=\"token operator\">&#061;<\/span> <span class=\"token keyword\">await<\/span> handle<span class=\"token punctuation\">.<\/span><span class=\"token function\">createWritable<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">await<\/span> writable<span class=\"token punctuation\">.<\/span><span class=\"token function\">write<\/span><span class=\"token punctuation\">(<\/span>blob<span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n  <span class=\"token keyword\">await<\/span> writable<span class=\"token punctuation\">.<\/span><span class=\"token function\">close<\/span><span class=\"token punctuation\">(<\/span><span class=\"token punctuation\">)<\/span><span class=\"token punctuation\">;<\/span><br \/>\n<span class=\"token punctuation\">}<\/span><\/p>\n<p>\u8981\u70b9&#xff1a;\u5982\u679c\u4ea7\u54c1\u9700\u8981&#034;\u5b9a\u4f4d&#034;\u80fd\u529b&#xff0c;\u5fc5\u987b\u8d70\u684c\u9762\u7aef\u6216\u63d0\u4f9b\u672c\u5730\u4ee3\u7406\u670d\u52a1&#xff1b;Web \u7aef\u53ea\u80fd\u505a&#034;\u4e0b\u8f7d &#043; \u63d0\u793a\u4fdd\u5b58\u8def\u5f84&#034;\u3002<\/p>\n<hr \/>\n<h4>\u4e94\u3001\u5e38\u89c1\u95ee\u9898\u4e0e\u6392\u9519\u6e05\u5355<\/h4>\n<table>\n<tr>\u73b0\u8c61\u53ef\u80fd\u539f\u56e0\u6392\u67e5\u65b9\u5411<\/tr>\n<tbody>\n<tr>\n<td>\u9884\u89c8\u7a7a\u767d<\/td>\n<td>\u63a5\u53e3\u8fd4\u56de 415 \/ 404<\/td>\n<td>\u68c0\u67e5 resolveArtifactStrategy \u4e0e\u8def\u7531<\/td>\n<\/tr>\n<tr>\n<td>\u4e2d\u6587\u6587\u4ef6\u540d\u4e71\u7801<\/td>\n<td>Content-Disposition \u672a\u7f16\u7801<\/td>\n<td>\u4f7f\u7528 filename*&#061;UTF-8&#039;&#039; \u6216 encodeURIComponent<\/td>\n<\/tr>\n<tr>\n<td>\u5927\u6587\u4ef6\u9884\u89c8\u5361\u6b7b<\/td>\n<td>\u672a\u505a\u622a\u65ad<\/td>\n<td>\u589e\u52a0 maxBytes \u53c2\u6570\u4e0e\u524d\u7aef\u63d0\u793a<\/td>\n<\/tr>\n<tr>\n<td>\u56fe\u7247\u9884\u89c8\u88c2\u56fe<\/td>\n<td>MIME \u7c7b\u578b\u9519\u8bef<\/td>\n<td>\u68c0\u67e5 guessMime \u6620\u5c04<\/td>\n<\/tr>\n<tr>\n<td>\u4e0b\u8f7d\u53d8\u6210\u5728\u7ebf\u6253\u5f00<\/td>\n<td>\u7f3a\u5c11 attachment<\/td>\n<td>\u8865 Content-Disposition<\/td>\n<\/tr>\n<tr>\n<td>\u5b9a\u4f4d\u5931\u8d25<\/td>\n<td>\u8def\u5f84\u7a7f\u8d8a\u62e6\u622a<\/td>\n<td>\u68c0\u67e5 safeResolve \u7684\u6839\u76ee\u5f55\u914d\u7f6e<\/td>\n<\/tr>\n<tr>\n<td>PDF \u9884\u89c8\u7a7a\u767d<\/td>\n<td>\u6d4f\u89c8\u5668\u7981\u7528\u4e86\u5185\u5d4c PDF<\/td>\n<td>\u63d0\u4f9b&#034;\u65b0\u7a97\u53e3\u6253\u5f00&#034;\u964d\u7ea7<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>\u8def\u5f84\u7a7f\u8d8a\u662f\u6700\u5bb9\u6613\u88ab\u5ffd\u89c6\u7684\u5b89\u5168\u95ee\u9898\u3002\u4efb\u4f55\u63a5\u53d7\u6587\u4ef6\u540d\u53c2\u6570\u7684\u63a5\u53e3&#xff0c;\u90fd\u5fc5\u987b\u505a\u6839\u76ee\u5f55\u524d\u7f00\u6821\u9a8c&#xff0c;\u4e14\u8981\u5904\u7406 ..\u3001\u7b26\u53f7\u94fe\u63a5\u7b49\u8fb9\u754c\u60c5\u51b5\u3002\u63a8\u8350\u4f7f\u7528 path.resolve \u540e\u518d\u6bd4\u8f83\u524d\u7f00&#xff0c;\u5982\u672c\u6587 safeResolve \u6240\u793a\u3002<\/p>\n<hr \/>\n<h3>\u603b\u7ed3<\/h3>\n<p>\u4ea7\u7269\u9884\u89c8\u4e0e\u6253\u5f00\u65b9\u5f0f\u770b\u4f3c\u662f&#034;\u70b9\u4e00\u4e0b\u6309\u94ae&#034;\u7684\u5c0f\u529f\u80fd&#xff0c;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u4ea7\u7269\u9884\u89c8\u4e0e\u6253\u5f00\u65b9\u5f0f<br \/>\n\u6458\u8981<br \/>\n\u5728\u73b0\u4ee3\u5f00\u53d1\u5de5\u5177\u3001AI \u7f16\u7a0b\u52a9\u624b\u3001CI\/CD \u5e73\u53f0\u4ee5\u53ca\u5404\u7c7b\u534f\u4f5c\u7cfb\u7edf\u4e2d&#xff0c;\\&#8221;\u4ea7\u7269&#xff08;Artifact&#xff09;\\&#8221;\u662f\u4e00\u4e2a\u9ad8\u9891\u51fa\u73b0\u7684\u6982\u5ff5\u3002\u5b83\u53ef\u80fd\u662f\u7f16\u8bd1\u751f\u6210\u7684\u4e8c\u8fdb\u5236\u6587\u4ef6\u3001\u6784\u5efa\u8f93\u51fa\u7684\u524d\u7aef\u8d44\u6e90\u5305\u3001\u6570\u636e\u5904\u7406\u7684\u4e2d\u95f4\u7ed3\u679c&#xff0c;\u4e5f\u53ef\u80fd\u662f\u4e00\u4efd AI \u751f\u6210\u7684\u62a5\u544a\u6587\u6863\u3002\u4ea7\u7269\u751f\u6210\u4e4b\u540e&#xff0c;\u7528\u6237\u6700\u5173\u5fc3\u7684\u95ee\u9898\u5f80\u5f80\u53ea\u6709\u4e00\u4e2a&#xff1a;\u6211\u8be5\u600e\u4e48\u67e5\u770b\u5b83&#xff1f;<br \/>\n\u672c\u6587\u56f4\u7ed5\\&#8221;\u53f3\u4fa7\u4ea7\u7269\u533a\\&#8221;\u8fd9\u4e00\u5178\u578b\u4ea4\u4e92\u573a\u666f&#xff0c;\u7cfb\u7edf\u8bb2\u89e3<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[868,52,175,50,427],"topic":[],"class_list":["post-119147","post","type-post","status-publish","format-standard","hentry","category-server","tag-868","tag-aigc","tag-chatgpt","tag-50","tag-427"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.3 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>WorkBuddy_\u4ea7\u7269\u4e0e\u5de5\u4f5c\u7a7a\u95f4\u7ba1\u74064_\u4ea7\u7269\u9884\u89c8\u4e0e\u6253\u5f00\u65b9\u5f0f - \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\/119147.html\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"WorkBuddy_\u4ea7\u7269\u4e0e\u5de5\u4f5c\u7a7a\u95f4\u7ba1\u74064_\u4ea7\u7269\u9884\u89c8\u4e0e\u6253\u5f00\u65b9\u5f0f - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"og:description\" content=\"\u4ea7\u7269\u9884\u89c8\u4e0e\u6253\u5f00\u65b9\u5f0f \u6458\u8981 \u5728\u73b0\u4ee3\u5f00\u53d1\u5de5\u5177\u3001AI \u7f16\u7a0b\u52a9\u624b\u3001CI\/CD \u5e73\u53f0\u4ee5\u53ca\u5404\u7c7b\u534f\u4f5c\u7cfb\u7edf\u4e2d&#xff0c;&quot;\u4ea7\u7269&#xff08;Artifact&#xff09;&quot;\u662f\u4e00\u4e2a\u9ad8\u9891\u51fa\u73b0\u7684\u6982\u5ff5\u3002\u5b83\u53ef\u80fd\u662f\u7f16\u8bd1\u751f\u6210\u7684\u4e8c\u8fdb\u5236\u6587\u4ef6\u3001\u6784\u5efa\u8f93\u51fa\u7684\u524d\u7aef\u8d44\u6e90\u5305\u3001\u6570\u636e\u5904\u7406\u7684\u4e2d\u95f4\u7ed3\u679c&#xff0c;\u4e5f\u53ef\u80fd\u662f\u4e00\u4efd AI \u751f\u6210\u7684\u62a5\u544a\u6587\u6863\u3002\u4ea7\u7269\u751f\u6210\u4e4b\u540e&#xff0c;\u7528\u6237\u6700\u5173\u5fc3\u7684\u95ee\u9898\u5f80\u5f80\u53ea\u6709\u4e00\u4e2a&#xff1a;\u6211\u8be5\u600e\u4e48\u67e5\u770b\u5b83&#xff1f; \u672c\u6587\u56f4\u7ed5&quot;\u53f3\u4fa7\u4ea7\u7269\u533a&quot;\u8fd9\u4e00\u5178\u578b\u4ea4\u4e92\u573a\u666f&#xff0c;\u7cfb\u7edf\u8bb2\u89e3\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.wsisp.com\/helps\/119147.html\" \/>\n<meta property=\"og:site_name\" content=\"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\" \/>\n<meta property=\"article:published_time\" content=\"2026-10-28T16:48:34+00:00\" \/>\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=\"6 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/119147.html\",\"url\":\"https:\/\/www.wsisp.com\/helps\/119147.html\",\"name\":\"WorkBuddy_\u4ea7\u7269\u4e0e\u5de5\u4f5c\u7a7a\u95f4\u7ba1\u74064_\u4ea7\u7269\u9884\u89c8\u4e0e\u6253\u5f00\u65b9\u5f0f - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3\",\"isPartOf\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#website\"},\"datePublished\":\"2026-10-28T16:48:34+00:00\",\"dateModified\":\"2026-10-28T16:48:34+00:00\",\"author\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.wsisp.com\/helps\/119147.html#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.wsisp.com\/helps\/119147.html\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.wsisp.com\/helps\/119147.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.wsisp.com\/helps\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"WorkBuddy_\u4ea7\u7269\u4e0e\u5de5\u4f5c\u7a7a\u95f4\u7ba1\u74064_\u4ea7\u7269\u9884\u89c8\u4e0e\u6253\u5f00\u65b9\u5f0f\"}]},{\"@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":"WorkBuddy_\u4ea7\u7269\u4e0e\u5de5\u4f5c\u7a7a\u95f4\u7ba1\u74064_\u4ea7\u7269\u9884\u89c8\u4e0e\u6253\u5f00\u65b9\u5f0f - \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\/119147.html","og_locale":"zh_CN","og_type":"article","og_title":"WorkBuddy_\u4ea7\u7269\u4e0e\u5de5\u4f5c\u7a7a\u95f4\u7ba1\u74064_\u4ea7\u7269\u9884\u89c8\u4e0e\u6253\u5f00\u65b9\u5f0f - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","og_description":"\u4ea7\u7269\u9884\u89c8\u4e0e\u6253\u5f00\u65b9\u5f0f \u6458\u8981 \u5728\u73b0\u4ee3\u5f00\u53d1\u5de5\u5177\u3001AI \u7f16\u7a0b\u52a9\u624b\u3001CI\/CD \u5e73\u53f0\u4ee5\u53ca\u5404\u7c7b\u534f\u4f5c\u7cfb\u7edf\u4e2d&#xff0c;\"\u4ea7\u7269&#xff08;Artifact&#xff09;\"\u662f\u4e00\u4e2a\u9ad8\u9891\u51fa\u73b0\u7684\u6982\u5ff5\u3002\u5b83\u53ef\u80fd\u662f\u7f16\u8bd1\u751f\u6210\u7684\u4e8c\u8fdb\u5236\u6587\u4ef6\u3001\u6784\u5efa\u8f93\u51fa\u7684\u524d\u7aef\u8d44\u6e90\u5305\u3001\u6570\u636e\u5904\u7406\u7684\u4e2d\u95f4\u7ed3\u679c&#xff0c;\u4e5f\u53ef\u80fd\u662f\u4e00\u4efd AI \u751f\u6210\u7684\u62a5\u544a\u6587\u6863\u3002\u4ea7\u7269\u751f\u6210\u4e4b\u540e&#xff0c;\u7528\u6237\u6700\u5173\u5fc3\u7684\u95ee\u9898\u5f80\u5f80\u53ea\u6709\u4e00\u4e2a&#xff1a;\u6211\u8be5\u600e\u4e48\u67e5\u770b\u5b83&#xff1f; \u672c\u6587\u56f4\u7ed5\"\u53f3\u4fa7\u4ea7\u7269\u533a\"\u8fd9\u4e00\u5178\u578b\u4ea4\u4e92\u573a\u666f&#xff0c;\u7cfb\u7edf\u8bb2\u89e3","og_url":"https:\/\/www.wsisp.com\/helps\/119147.html","og_site_name":"\u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","article_published_time":"2026-10-28T16:48:34+00:00","author":"admin","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"admin","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"6 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.wsisp.com\/helps\/119147.html","url":"https:\/\/www.wsisp.com\/helps\/119147.html","name":"WorkBuddy_\u4ea7\u7269\u4e0e\u5de5\u4f5c\u7a7a\u95f4\u7ba1\u74064_\u4ea7\u7269\u9884\u89c8\u4e0e\u6253\u5f00\u65b9\u5f0f - \u7f51\u7855\u4e92\u8054\u5e2e\u52a9\u4e2d\u5fc3","isPartOf":{"@id":"https:\/\/www.wsisp.com\/helps\/#website"},"datePublished":"2026-10-28T16:48:34+00:00","dateModified":"2026-10-28T16:48:34+00:00","author":{"@id":"https:\/\/www.wsisp.com\/helps\/#\/schema\/person\/358e386c577a3ab51c4493330a20ad41"},"breadcrumb":{"@id":"https:\/\/www.wsisp.com\/helps\/119147.html#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.wsisp.com\/helps\/119147.html"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.wsisp.com\/helps\/119147.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.wsisp.com\/helps"},{"@type":"ListItem","position":2,"name":"WorkBuddy_\u4ea7\u7269\u4e0e\u5de5\u4f5c\u7a7a\u95f4\u7ba1\u74064_\u4ea7\u7269\u9884\u89c8\u4e0e\u6253\u5f00\u65b9\u5f0f"}]},{"@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\/119147","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=119147"}],"version-history":[{"count":0,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/posts\/119147\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/media?parent=119147"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/categories?post=119147"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/tags?post=119147"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.wsisp.com\/helps\/wp-json\/wp\/v2\/topic?post=119147"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}