浏览器的copy as fetch和copy as bash的区别
位置:devTools->network->请求列表右键
copy as fetch
fetch("https://www.kuaishou.com/graphql", {"headers": {"accept": "*/*","accept-language": "en,zh-CN;q=0.9,zh;q=0.8","cache-control": "no-cache","content-type": "application/json","pragma": "no-cache","sec-ch-ua": "\"Google Chrome\";v=\"129\", \"Not=A?Brand\";v=\"8\", \"Chromium\";v=\"129\"","sec-ch-ua-mobile": "?0","sec-ch-ua-platform": "\"Windows\"","sec-fetch-dest": "empty","sec-fetch-mode": "cors","sec-fetch-site": "same-origin"},"referrer": "https://www.kuaishou.com/search/video?searchKey=22","referrerPolicy": "unsafe-url","body": "{\"operationName\":\"visionSearchPhoto\",\"variables\":{\"keyword\":\"22\",\"pcursor\":\"\",\"page\":\"search\"},\"query\":\"fragment photoContent on PhotoEntity {\\n  __typename\\n  id\\n  duration\\n  caption\\n  originCaption\\n  likeCount\\n  viewCount\\n  commentCount\\n  realLikeCount\\n  coverUrl\\n  photoUrl\\n  photoH265Url\\n  manifest\\n  manifestH265\\n  videoResource\\n  coverUrls {\\n    url\\n    __typename\\n  }\\n  timestamp\\n  expTag\\n  animatedCoverUrl\\n  distance\\n  videoRatio\\n  liked\\n  stereoType\\n  profileUserTopPhoto\\n  musicBlocked\\n  riskTagContent\\n  riskTagUrl\\n}\\n\\nfragment recoPhotoFragment on recoPhotoEntity {\\n  __typename\\n  id\\n  duration\\n  caption\\n  originCaption\\n  likeCount\\n  viewCount\\n  commentCount\\n  realLikeCount\\n  coverUrl\\n  photoUrl\\n  photoH265Url\\n  manifest\\n  manifestH265\\n  videoResource\\n  coverUrls {\\n    url\\n    __typename\\n  }\\n  timestamp\\n  expTag\\n  animatedCoverUrl\\n  distance\\n  videoRatio\\n  liked\\n  stereoType\\n  profileUserTopPhoto\\n  musicBlocked\\n  riskTagContent\\n  riskTagUrl\\n}\\n\\nfragment feedContent on Feed {\\n  type\\n  author {\\n    id\\n    name\\n    headerUrl\\n    following\\n    headerUrls {\\n      url\\n      __typename\\n    }\\n    __typename\\n  }\\n  photo {\\n    ...photoContent\\n    ...recoPhotoFragment\\n    __typename\\n  }\\n  canAddComment\\n  llsid\\n  status\\n  currentPcursor\\n  tags {\\n    type\\n    name\\n    __typename\\n  }\\n  __typename\\n}\\n\\nquery visionSearchPhoto($keyword: String, $pcursor: String, $searchSessionId: String, $page: String, $webPageArea: String) {\\n  visionSearchPhoto(keyword: $keyword, pcursor: $pcursor, searchSessionId: $searchSessionId, page: $page, webPageArea: $webPageArea) {\\n    result\\n    llsid\\n    webPageArea\\n    feeds {\\n      ...feedContent\\n      __typename\\n    }\\n    searchSessionId\\n    pcursor\\n    aladdinBanner {\\n      imgUrl\\n      link\\n      __typename\\n    }\\n    __typename\\n  }\\n}\\n\"}","method": "POST","mode": "cors","credentials": "include"
}); 
copy as bash
curl 'https://www.kuaishou.com/graphql' \-H 'Accept-Language: en,zh-CN;q=0.9,zh;q=0.8' \-H 'Cache-Control: no-cache' \-H 'Connection: keep-alive' \-H 'Cookie: weblogger_did=web_140476153E50FC40; kpf=PC_WEB; clientid=3; did=web_6c1bfef1bff5f0e063c16c6381ffc8d0; userId=1926344872; kuaishou.server.webday7_st=ChprdWFpc2hxxxxxxxxxxF5Ny5zdBKwAU-QhpLs58EqWw14KtRN3ktXeVV4IUBH-whoUB9UX3l00ZEd9B3n9SpIk9BsUuMCrjTDKxxxxxxxxxcCZg_WwoR6sy5p6VyZobi7CqqXtr-8XLF7slXPq8_PhjMjB5BRkekJPuKCZCSYTPMFYUWTr1AJEzk2Zt-eTtZox9VWK6XPjUUhVxxxxxxxxEG-4f5yJd10AXaDXiGhJglXWxx8RvW8kJJMTzKPTd1I8iIGnzLs4NhZYSpkCR8AmlC8W8L-ZzYA0UByzvqOerFQahKAUwAQ; kuaishou.server.webday7_ph=1b4a3594exxxxxxxxx3531408cb; kpn=KUAISHOU_VISION' \-H 'Origin: https://www.kuaishou.com' \-H 'Pragma: no-cache' \-H 'Referer: https://www.kuaishou.com/search/video?searchKey=22' \-H 'Sec-Fetch-Dest: empty' \-H 'Sec-Fetch-Mode: cors' \-H 'Sec-Fetch-Site: same-origin' \-H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36' \-H 'accept: */*' \-H 'content-type: application/json' \-H 'sec-ch-ua: "Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"' \-H 'sec-ch-ua-mobile: ?0' \-H 'sec-ch-ua-platform: "Windows"' \--data-raw '{"operationName":"visionSearchPhoto","variables":{"keyword":"22","pcursor":"","page":"search"},"query":"fragment photoContent on PhotoEntity {\n  __typename\n  id\n  duration\n  caption\n  originCaption\n  likeCount\n  viewCount\n  commentCount\n  realLikeCount\n  coverUrl\n  photoUrl\n  photoH265Url\n  manifest\n  manifestH265\n  videoResource\n  coverUrls {\n    url\n    __typename\n  }\n  timestamp\n  expTag\n  animatedCoverUrl\n  distance\n  videoRatio\n  liked\n  stereoType\n  profileUserTopPhoto\n  musicBlocked\n  riskTagContent\n  riskTagUrl\n}\n\nfragment recoPhotoFragment on recoPhotoEntity {\n  __typename\n  id\n  duration\n  caption\n  originCaption\n  likeCount\n  viewCount\n  commentCount\n  realLikeCount\n  coverUrl\n  photoUrl\n  photoH265Url\n  manifest\n  manifestH265\n  videoResource\n  coverUrls {\n    url\n    __typename\n  }\n  timestamp\n  expTag\n  animatedCoverUrl\n  distance\n  videoRatio\n  liked\n  stereoType\n  profileUserTopPhoto\n  musicBlocked\n  riskTagContent\n  riskTagUrl\n}\n\nfragment feedContent on Feed {\n  type\n  author {\n    id\n    name\n    headerUrl\n    following\n    headerUrls {\n      url\n      __typename\n    }\n    __typename\n  }\n  photo {\n    ...photoContent\n    ...recoPhotoFragment\n    __typename\n  }\n  canAddComment\n  llsid\n  status\n  currentPcursor\n  tags {\n    type\n    name\n    __typename\n  }\n  __typename\n}\n\nquery visionSearchPhoto($keyword: String, $pcursor: String, $searchSessionId: String, $page: String, $webPageArea: String) {\n  visionSearchPhoto(keyword: $keyword, pcursor: $pcursor, searchSessionId: $searchSessionId, page: $page, webPageArea: $webPageArea) {\n    result\n    llsid\n    webPageArea\n    feeds {\n      ...feedContent\n      __typename\n    }\n    searchSessionId\n    pcursor\n    aladdinBanner {\n      imgUrl\n      link\n      __typename\n    }\n    __typename\n  }\n}\n"}'
 
两个代码片段分别是使用 JavaScript 的 fetch API 和命令行工具 curl 发起的 POST 请求,目标均为快手的 GraphQL 接口 https://www.kuaishou.com/graphql,用于搜索关键词为 22 的视频数据。以下是两者的核心区别:
1. 协议与用途
-  
fetch- 属于 浏览器原生 API,用于在前端(如网页脚本)中发起网络请求。
 - 依赖浏览器环境,支持浏览器特有的功能(如 
credentials: "include"自动携带同源 Cookie)。 
 -  
curl- 是 命令行工具,用于在终端(如 Linux/macOS/Windows 的命令提示符)中模拟网络请求。
 - 独立于浏览器,需手动指定所有请求参数(如 Cookie、User-Agent 等)。
 
 
2. 请求头(Headers)
-  
共同点
- 核心请求头(如 
Accept、Content-Type、Referer、Sec-Fetch-*等)几乎完全一致,均声明了请求为 JSON 格式、跨域模式(CORS)、来源为搜索页面https://www.kuaishou.com/search/video?searchKey=22。 
 - 核心请求头(如 
 -  
差异点
curl额外包含:Cookie头:显式携带浏览器存储的 Cookie(如用户登录状态、设备标识等),而fetch中未显式声明,但通过credentials: "include"会自动发送同源 Cookie。User-Agent:明确指定浏览器指纹(Mozilla/5.0 (Windows NT 10.0...),fetch中浏览器会默认添加,但代码中未显式写出。Connection: keep-alive:保持长连接,fetch会自动处理,无需手动声明。
fetch额外包含:referrerPolicy: "unsafe-url":控制 Referer 头的发送策略,curl中无此参数(直接使用Referer头)。
 
3. 请求体(Body)
- 内容完全一致:
均为 GraphQL 查询字符串,包含operationName(visionSearchPhoto)、搜索关键词keyword: "22"、以及复杂的字段片段(fragment),用于获取视频的详细信息(如 ID、播放量、封面链接等)。 - 格式差异: 
fetch中需将请求体转换为字符串("body": JSON.stringify(...),但用户代码中已直接使用字符串)。curl中通过--data-raw直接传递原始 JSON 数据,无需额外处理。
 
4. Cookie 处理
-  
fetch:- 通过 
credentials: "include"声明跨域请求时携带 Cookie(需目标域名支持Access-Control-Allow-Credentials: true)。 - 浏览器自动读取当前域名下的 Cookie 并添加到请求中,代码中无需显式写入 
Cookie头。 
 - 通过 
 -  
curl:- 必须手动在 
Cookie头中写入完整的 Cookie 字符串(如用户提供的weblogger_did=...; kpf=PC_WEB; ...),否则服务端可能无法识别用户状态(如登录信息)。 
 - 必须手动在 
 
5. 使用场景
-  
fetch:- 用于前端代码(如网页脚本)中,动态获取数据并渲染页面(例如快手搜索结果页的视频列表)。
 - 受浏览器同源策略、跨域限制(需服务端配置 CORS)。
 
 -  
curl:- 用于调试、抓包分析(如通过浏览器开发者工具获取请求后,用 
curl复现)、自动化脚本(如爬虫、数据采集)。 - 可绕过浏览器限制,直接构造任意请求(需手动处理所有参数,包括签名、加密等)。
 
 - 用于调试、抓包分析(如通过浏览器开发者工具获取请求后,用 
 
总结
两者本质上是 同一请求的不同实现方式:fetch 是浏览器环境下的前端代码,依赖浏览器自动处理部分参数(如 Cookie、User-Agent);curl 是独立的命令行工具,需手动指定所有细节,适合调试和非浏览器环境下的请求模拟。核心差异在于 环境依赖、Cookie 处理方式 和 参数声明的显式程度。这段代码展示了两种向快手 GraphQL API 发送请求的方式,分别使用了浏览器的 fetch API 和命令行工具 curl。它们的主要区别包括:
-  
运行环境
fetch:在浏览器环境中执行,受浏览器安全策略限制(如 CORS)。curl:在命令行或后端环境中执行,没有跨域限制。
 -  
Cookie 处理
fetch:通过credentials: "include"携带 cookies,但需要服务器明确允许(Access-Control-Allow-Credentials)。curl:直接在请求头中包含完整的 cookies(如weblogger_did、userId等),无需额外配置。
 -  
请求头差异
curl包含了Connection: keep-alive和完整的Cookie信息。fetch没有显式设置Connection头,依赖浏览器默认行为。
 -  
数据格式
fetch:使用 JavaScript 对象定义请求参数。curl:使用命令行参数和原始字符串数据。
 -  
实际效果
fetch:可能因缺少有效 cookies 或 CORS 配置失败。curl:由于携带完整 cookies,更有可能成功获取数据。
 
总结:curl 请求更完整(包含 cookies),适合后端或脚本环境;fetch 请求需要浏览器环境支持,且需服务器配合 CORS 策略。如果直接运行,curl 更可能成功获取数据。