【问题标题】:axios.get() error: true with 403 error code?axios.get() 错误:403 错误代码为真?
【发布时间】:2022-01-28 22:54:50
【问题描述】:

我在nodejs中调用了第三方api(solana区块链上的magiceden),但返回了403错误。
它没有任何 UI,它只是一个 api 函数调用!
'isAxiosError: true' 日志结果。
api调用在get方法中进行。
于是我在浏览器中输入了req url,显示成功结果。
我的意思是 url 在浏览器上返回成功的结果,但是通过 axios.get() 请求它失败了。

'Error: Request failed with status code 403
at createError (..\createError.js:16:15)
at settle (C:\workspace\solana-wallet-nft-track-secondary_market\node_modules\axios\lib\core\settle.js:17:12)
at IncomingMessage.handleStreamEnd (C:\workspace\solana-wallet-nft-track-secondary_market\node_modules\axios\lib\adapters\http.js:293:11)
at IncomingMessage.emit (node:events:402:35)
at IncomingMessage.emit (node:domain:475:12)
at endReadableNT (node:internal/streams/readable:1343:12)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
config: {
transitional: {
  silentJSONParsing: true,
  forcedJSONParsing: true,
  clarifyTimeoutError: false
},

headers: {
  Accept: 'application/json, text/plain, */*',
  'Access-Control-Allow-Origin': '*',
  'User-Agent': 'axios/0.24.0'
},
method: 'get',
url: 'https://api-mainnet.magiceden.io/rpc/getGlobalActivitiesByQuery?q={"%24match"%3A{"txType"%3A"initializeEscrow"%2C"blockTime"%3A{"%24gt"%3A1643376700}}%2C"%24sort"%3A{"blockTime"%3A-1}}',
data: undefined
},

...
},
response: {
status: 403,
statusText: 'Forbidden',
headers: {
  date: 'Fri, 28 Jan 2022 13:33:20 GMT',
  'content-type': 'text/html; charset=UTF-8',
  'transfer-encoding': 'chunked',
  connection: 'close',
  'cf-chl-bypass': '1',
  'permissions-policy': 'accelerometer=(),autoplay=(),camera=(),clipboard-read=(),clipboard-write=(),fullscreen=(),geolocation=(),gyroscope=(),hid=(),interest-cohort=(),magnetometer=(),microphone=(),payment=(),publickey-credentials-get=(),screen-wake-lock=(),serial=(),sync-xhr=(),usb=()',
  'cache-control': 'private, max-age=0, no-store, no-cache, must-revalidate, post-check=0, pre-check=0',
  expires: 'Thu, 01 Jan 1970 00:00:01 GMT',
  'x-frame-options': 'SAMEORIGIN',
  'expect-ct': 'max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"',
  server: 'cloudflare',
  'cf-ray': '6d4a978a9f812059-NRT',
  'alt-svc': 'h3=":443"; ma=86400, h3-29=":443"; ma=86400'
},
config: {
 
},
request: <ref *1> ClientRequest {
  _events: [Object: null prototype],
  _eventsCount: 7,
  _maxListeners: undefined,
  outputData: [],
  outputSize: 0,
  writable: true,
  destroyed: false,
  _last: true,
  chunkedEncoding: false,
  shouldKeepAlive: false,
  maxRequestsOnConnectionReached: false,
  _defaultKeepAlive: true,
  useChunkedEncodingByDefault: false,
  sendDate: false,
  _removedConnection: false,
  _removedContLen: false,
  _removedTE: false,
  _contentLength: 0,
  _hasBody: true,
  _trailer: '',
  finished: true,
  _headerSent: true,
  _closed: false,
  socket: [TLSSocket],
  _header: 'GET /rpc/getGlobalActivitiesByQuery?q=%7B%22%24match%22%3A%7B%22txType%22%3A%22initializeEscrow%22%2C%22blockTime%22%3A%7B%22%24gt%22%3A1643376700%7D%7D%2C%22%24sort%22%3A%7B%22blockTime%22%3A-1%7D%7D HTTP/1.1\r\n' +
    'Accept: application/json, text/plain, */*\r\n' +
    'Access-Control-Allow-Origin: *\r\n' +
    'User-Agent: axios/0.24.0\r\n' +
    'Host: api-mainnet.magiceden.io\r\n' +
    'Connection: close\r\n' +
    '\r\n',
  _keepAliveTimeout: 0,
  _onPendingData: [Function: nop],
  agent: [Agent],
  socketPath: undefined,
  method: 'GET',
  maxHeaderSize: undefined,
  insecureHTTPParser: undefined,
  path: '/rpc/getGlobalActivitiesByQuery?q=%7B%22%24match%22%3A%7B%22txType%22%3A%22initializeEscrow%22%2C%22blockTime%22%3A%7B%22%24gt%22%3A1643376700%7D%7D%2C%22%24sort%22%3A%7B%22blockTime%22%3A-1%7D%7D',
  _ended: true,
  res: [IncomingMessage],
  aborted: false,
  timeoutCb: null,
  upgradeOrConnect: false,
  parser: null,
  maxHeadersCount: null,
  reusedSocket: false,
  host: 'api-mainnet.magiceden.io',
  protocol: 'https:',
  _redirectable: [Writable],
  [Symbol(kCapture)]: false,
  [Symbol(kNeedDrain)]: false,
  [Symbol(corked)]: 0,
  [Symbol(kOutHeaders)]: [Object: null prototype]
  },
  data: ''
  isAxiosError: true,
  toJSON: [Function: toJSON]

【问题讨论】:

  • statusText: 'Forbidden' --> 需要认证?还是被 CORS 阻止了?编辑:不,我在浏览器中粘贴了 URL,直接得到了 JSON 结果。错误在您的代码中
  • 'Access-Control-Allow-Origin': '*', 是响应头,为什么要添加到请求中?
  • 它说请求禁止,我在日志中看不到任何凭据。为什么它应该允许你访问?
  • @JeremyThille — 不会是 CORS,这是 node.js。
  • 这很有趣:它在浏览器请求时起作用,而不是在非浏览器请求时起作用(例如,wget 或显然是 Node.js);它返回 403。显然,浏览器正在发送一些它想要的标头。

标签: javascript node.js api


【解决方案1】:

您尝试使用的资源做了一件相当微妙的事情:

  • 它返回一个 403(禁止)响应,其中 HTML 显示错误页面。
  • 自定义 HTML 嵌入了经过混淆处理的 JavaScript,它会做一些事情(大概是为了保护目标免受 DDoS 攻击等),然后将当前页面替换为您真正想要的响应(通过history.replaceState)。

启用了 JavaScript 的浏览器会在错误页面上运行 JavaScript,并以如此快的速度替换它,您根本不会注意到。但是axios 只是将错误页面返回给您的代码。

这似乎是通过 CloudFlare 完成的。它可能是为了防止僵尸程序或类似的。我相信我们都看到“CloudFlare 正在检查您的浏览器...”页面有时会在我们请求的真实内容出现之前出现。这似乎属于类似的类别。

【讨论】:

  • 你可以在浏览器上从url看到返回的结果:api-mainnet.magiceden.io/rpc/getGlobalActivitiesByQuery?q={"%24match"%3A{"txType"%3A"initializeEscrow"%2C"blockTime"%3A{"% 24gt"%3A1643376700}}%2C"%24sort"%3A{"blockTime"%3A-1}} 但正如我提到的 axios.get() 响应仍然失败。我认为是因为连接设置问题,不确定正确的解决方案
  • @ASSASSIN1030 - 不,这是因为响应的完成方式,如上所述。 CloudFlare 似乎在做一些相当复杂的事情,但它的主要基础似乎是:在错误页面中返回带有 JavaScript 的 403,当运行时,用 JSON 替换错误页面。
  • @TJ。 Crowder - 无论如何,在浏览器中,req url 显示成功结果。我认为在这样的 req 模式下,我可以在 axios.get() 中得到成功的结果。但我不知道该怎么做。如果是因为服务器端的问题,有什么办法可以解决这个问题吗?
  • 所以我认为 JSON 内容应该可以通过像 Puppeteer 这样的无头浏览器访问,而不是简单的 HTTP 调用?
  • @JeremyThille - 我假设是这样,除非 CloudFlare 的检查不允许这样做。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多