我试图从Chrome浏览器复制一个请求。当我打开url https://ticket.bolshoi.ru/shows时,有一个对https://ticket.bolshoi.ru/api/v1/client/shows的GET请求,返回json。我从DevTools复制了cURL请求。下面是我得到的:
curl 'https://ticket.bolshoi.ru/api/v1/client/shows' \
-H 'Accept: application/json, text/plain, */*' \
-H 'Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7' \
-H 'Connection: keep-alive' \
-H 'Cookie: skipped for security reason' \
-H 'Referer: https://ticket.bolshoi.ru/shows' \
-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/118.0.0.0 Safari/537.36' \
-H 'sec-ch-ua: "Chromium";v="118", "Google Chrome";v="118", "Not=A?Brand";v="99"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'sec-ch-ua-platform: "Windows"' \
--compressed
字符串
但是当我在bash shell中运行这个命令时,我得到的响应是一个html页面而不是json。为什么会这样?如何复制请求?
更新这里是如果我将-Lkv
键添加到curl
命令的输出
* Trying 185.169.155.232:443...
* Connected to ticket.bolshoi.ru (185.169.155.232) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /Users/xxx/opt/anaconda3/ssl/cacert.pem
* CApath: none
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN, server accepted to use http/1.1
* Server certificate:
* subject: CN=ticket.bolshoi.ru
* start date: Oct 11 23:02:07 2023 GMT
* expire date: Jan 9 23:02:06 2024 GMT
* issuer: C=US; O=Let's Encrypt; CN=R3
* SSL certificate verify ok.
> GET /shows HTTP/1.1
> Host: ticket.bolshoi.ru
> Accept-Encoding: deflate, gzip
> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
> Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
> Cache-Control: no-cache
> Connection: keep-alive
> Cookie: spid=xxx; lang=xxx; sails.sid=xxx; spsc=xxx
> Pragma: no-cache
> Sec-Fetch-Dest: document
> Sec-Fetch-Mode: navigate
> Sec-Fetch-Site: cross-site
> Sec-Fetch-User: ?1
> Upgrade-Insecure-Requests: 1
> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/118.0.0.0 Safari/537.36
> sec-ch-ua: "Chromium";v="118", "Google Chrome";v="118", "Not=A?Brand";v="99"
> sec-ch-ua-mobile: ?0
> sec-ch-ua-platform: "macOS"
>
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx
< Date: Wed, 15 Nov 2023 19:09:06 GMT
< Transfer-Encoding: chunked
< Connection: keep-alive
< Keep-Alive: timeout=15
< access-control-allow-origin: *
< cache-control: no-cache
< expires: Wed, 15 Nov 2023 19:0905 GMT
< pragma: no-cache
< content-type: text/html
< X-SP-CRID: xxx:1
<
<!DOCTYPE html>
...
</html>
* Connection #0 to host ticket.bolshoi.ru left intact
型
**
以下是来自Web浏览器的一些屏幕截图:
1条答案
按热度按时间piok6c0g1#
curl
命令的详细输出确认在端口443上成功连接到ticket.bolshoi.ru
,这意味着基本连接没有问题。请求头似乎设置得很好。但是,
Accept
头被设置为接受HTML(text/html
),XML,图像和其他类型,而不是显式JSON。这可能是服务器响应HTML页面而不是JSON响应的原因。响应头表明服务器正在使用
text/html
的内容类型进行响应,这与您获得的HTML响应而不是JSON相匹配。因此,请尝试更改cURL请求中的
Accept
标头,以显式地请求JSON。例如:
-H 'Accept: application/json'
。它通知服务器您正在等待JSON响应。假设cURL命令(
https://ticket.bolshoi.ru/api/v1/client/shows
)中的URL是获取JSON数据的正确端点,那么cURL命令的更新版本将是:字符串
已尝试此操作但未成功。响应仍然是HTML页面。
如果通过浏览器访问相同的URL时返回JSON,请考虑浏览器可能正在发送未包含在cURL命令中的其他会话数据或Cookie。有时,API会根据会话特定数据提供不同的内容。如果您尚未复制浏览器请求中的所有Cookie,请尝试将它们包含在cURL命令中。
服务器可能会区分浏览器(通常可以处理HTML和JavaScript)发出的请求和cURL(通常需要JSON等原始数据)等非浏览器客户端发出的请求。这种区分可以基于
Accept
以外的头,例如User-Agent
。尝试在cURL命令中更改User-Agent
以模拟不同的浏览器,并查看响应是否发生变化。使用浏览器开发工具中的网络检查器来检查访问URL时发出的确切请求。这可以深入了解浏览器请求和cURL命令之间的任何差异。
确保浏览器发送的所有头都在cURL请求中复制,而不仅仅是
Accept
头。这包括cookie,用户代理和任何其他可能影响服务器响应的头。如果
https://ticket.bolshoi.ru/shows
处的页面执行JavaScript来获取JSON数据,则cURL命令不会复制此行为,因为它不执行JavaScript。如果在初始页面加载后通过JavaScript动态加载JSON数据,则这一点尤其重要。您提供的屏幕截图显示了对
https://ticket.bolshoi.ru/api/v1/client/shows
的成功浏览器请求,该请求返回JSON,如Content-Type
响应头为application/json;charset=UTF-8
所示。它还显示服务器正在使用
gzip
内容编码。确保curl
可以使用--compressed
处理gzip响应。响应头指示
no-cache, no-store, must-revalidate
和keep-alive
。虽然curl
默认不缓存,但使用-H 'Connection: keep-alive'
确保连接持久性可能会更准确地反映浏览器行为。服务器可以根据
User-Agent
字符串提供不同的内容。如果您还没有在curl
命令中匹配浏览器请求中的User-Agent
,请匹配。如果您的
curl
命令中没有包含浏览器会话中涉及的Cookie,则这可能是服务器正确响应所必需的。您可以尝试在curl
命令中包含浏览器请求中的所有Cookie。虽然屏幕截图中没有显示,但有时服务器会检查
Referer
和Origin
头来服务请求。如果您的浏览器请求包含这些,您也应该在curl
命令中包含它们。下面是一个
curl
命令模板,您可以修改它以包含浏览器请求中的所有相关标头:型
将占位符(例如
[all cookies from browser]
、[referer from the browser]
、[user-agent from the browser]
)替换为浏览器请求中的实际值。-L
标志将跟随重定向,-k
将忽略SSL验证(谨慎使用),-v
将给予详细输出以进行调试。