【一】浏览器的copy as fetch和copy as bash的区别

发布于:2025-05-10 ⋅ 阅读:(18) ⋅ 点赞:(0)

浏览器的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)

  • 共同点

    • 核心请求头(如 AcceptContent-TypeRefererSec-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 查询字符串,包含 operationNamevisionSearchPhoto)、搜索关键词 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。它们的主要区别包括:

  1. 运行环境

    • fetch:在浏览器环境中执行,受浏览器安全策略限制(如 CORS)。
    • curl:在命令行或后端环境中执行,没有跨域限制。
  2. Cookie 处理

    • fetch:通过 credentials: "include" 携带 cookies,但需要服务器明确允许(Access-Control-Allow-Credentials)。
    • curl:直接在请求头中包含完整的 cookies(如 weblogger_diduserId 等),无需额外配置。
  3. 请求头差异

    • curl 包含了 Connection: keep-alive 和完整的 Cookie 信息。
    • fetch 没有显式设置 Connection 头,依赖浏览器默认行为。
  4. 数据格式

    • fetch:使用 JavaScript 对象定义请求参数。
    • curl:使用命令行参数和原始字符串数据。
  5. 实际效果

    • fetch:可能因缺少有效 cookies 或 CORS 配置失败。
    • curl:由于携带完整 cookies,更有可能成功获取数据。

总结curl 请求更完整(包含 cookies),适合后端或脚本环境;fetch 请求需要浏览器环境支持,且需服务器配合 CORS 策略。如果直接运行,curl 更可能成功获取数据。


网站公告

今日签到

点亮在社区的每一天
去签到