下载URL分别取回,保留同屏版本对应关系
本页展示随包原生输入和验收参考。目标产品运行状态:未运行。表格与图片不代表产品已经生成的结果。
input.csv / practice-data.json
本课实际输入字段
| artifact | method | returns | screenRoute | pairKey |
|---|---|---|---|---|
| html | screen.getHtml() | download URL | ||
| image | screen.getImage() | download URL | ||
| /booking | booking-reviewed-v1 |
下载并检查类型
reference.csv:作者验收映射,不是目标API回包
| file | mustContain | mustMatch | failure | action |
|---|---|---|---|---|
| booking.html | <!doctype or <html structure | |||
| booking.webp/png | same screen text and layout | |||
| HTML error response | reject as asset |
规则与输入文件原文
{
"inputRows": [
{
"artifact": "html",
"method": "screen.getHtml()",
"returns": "download URL"
},
{
"artifact": "image",
"method": "screen.getImage()",
"returns": "download URL"
},
{
"screenRoute": "/booking",
"pairKey": "booking-reviewed-v1"
}
],
"referenceRows": [
{
"file": "booking.html",
"mustContain": "<!doctype or <html structure"
},
{
"file": "booking.webp/png",
"mustMatch": "same screen text and layout"
},
{
"failure": "HTML error response",
"action": "reject as asset"
}
],
"invalidRows": [
{
"file": "index.html",
"content": "https://example.invalid/download",
"error": "URL saved as content"
},
{
"pair": [
"old HTML",
"new screenshot"
],
"error": "mismatched version"
}
],
"notes": [
"全部输入为作者自制教学资料,不含真实客户或账号。",
"referenceRows是校验基准,不是目标模型预测或识别结果;targetProduct=not_run。"
],
"files": {
"input.json": "[\n {\n \"artifact\": \"html\",\n \"method\": \"screen.getHtml()\",\n \"returns\": \"download URL\"\n },\n {\n \"artifact\": \"image\",\n \"method\": \"screen.getImage()\",\n \"returns\": \"download URL\"\n },\n {\n \"screenRoute\": \"/booking\",\n \"pairKey\": \"booking-reviewed-v1\"\n }\n]\n",
"reference.json": "{\n \"identity\": \"作者验收参考,非模型返回\",\n \"rows\": [\n {\n \"file\": \"booking.html\",\n \"mustContain\": \"<!doctype or <html structure\"\n },\n {\n \"file\": \"booking.webp/png\",\n \"mustMatch\": \"same screen text and layout\"\n },\n {\n \"failure\": \"HTML error response\",\n \"action\": \"reject as asset\"\n }\n ]\n}\n",
"invalid.json": "{\n \"identity\": \"作者构造负例,非实际错误回包\",\n \"rows\": [\n {\n \"file\": \"index.html\",\n \"content\": \"https://example.invalid/download\",\n \"error\": \"URL saved as content\"\n },\n {\n \"pair\": [\n \"old HTML\",\n \"new screenshot\"\n ],\n \"error\": \"mismatched version\"\n }\n ]\n}\n",
"case.md": "# Stitch导出HTML和截图:下载URL分别取回,保留同屏版本对应关系\n\nStitch导出HTML和截图先分清返回值是下载地址。用相同screen的HTML和图片成对保存,检查内容类型及版本,防止把URL字符串写成index.html。\n\n## 锁定同一屏幕\n\n从项目读取目标screen,记录screenId和版本时间。\n\n不要一个方法用旧引用、另一个方法重新选最新页面。\n\n## 获取两种下载地址\n\n分别await screen.getHtml()和screen.getImage()。\n\n官方SDK返回URL,不是HTML字符串或图片字节。\n\n## 下载并检查类型\n\n在授权环境取回两个URL,将HTML和图片写到不同文件。\n\n若返回错误页或鉴权失败,保存状态并停止,不按扩展名伪装成功。\n\n## 检查HTML内容\n\n确认文件含HTML结构与页面文字,而非一行https链接。\n\n如果下载页面依赖外链资源,另外记录依赖,不默认单文件离线可用。\n\n## 配对截图和源码\n\n给两份文件相同screen键与取得时间,打开检查标题、布局和文案。\n\n图片与HTML不一致时先核对来源,不手工改图掩盖版本差异。\n\n## 处理过期资源\n\n地址失效时从同一目标screen重新读取新下载地址。\n\n不要把旧URL当永久公开资源写进长期教程素材。\n\n## 交付导出清单\n\n保存本地文件、内容类型和屏幕身份,删除日志中不必要的临时敏感参数。\n\n未执行下载时仍为待验证,不称源码已运行。\n\n身份:输入与参考为作者材料;localCli有实测记录时仅证明对应CLI运行,目标云端与模型推理未执行。\n",
"download.ts": "import { stitch } from \"@google/stitch-sdk\";\nimport {writeFile} from \"node:fs/promises\";\nconst projectId=process.env.STITCH_PROJECT_ID;const screenId=process.env.STITCH_SCREEN_ID;\nif(!projectId||!screenId)throw new Error(\"Set actual bare project/screen IDs in environment\");\nconst screen=await stitch.project(projectId).getScreen(screenId);\nfor(const [kind,url] of [[\"html\",await screen.getHtml()],[\"image\",await screen.getImage()]] as const){\n const response=await fetch(url);if(!response.ok)throw new Error(`download ${kind} ${response.status}`);\n const type=response.headers.get(\"content-type\")??\"\";\n if(kind===\"html\"&&!type.includes(\"text/html\"))throw new Error(\"unexpected HTML content type\");\n if(kind===\"image\"&&!type.startsWith(\"image/\"))throw new Error(\"unexpected image content type\");\n await writeFile(kind===\"html\"?\"screen.html\":\"screen.image\",new Uint8Array(await response.arrayBuffer()));\n}\n"
}
}应当保留的约束
| file | mustContain | mustMatch | failure | action |
|---|---|---|---|---|
| booking.html | <!doctype or <html structure | |||
| booking.webp/png | same screen text and layout | |||
| HTML error response | reject as asset |
故意构造的错误样例
| file | content | error | pair |
|---|---|---|---|
| index.html | https://example.invalid/download | URL saved as content | |
| mismatched version | ["old HTML", "new screenshot"] |
先保存真实产品输出,再逐项对照。actualOutput / actualResult 在未执行时保持 not_run,不能把这里的期望值复制成已测结果。