如何在 JavaScript 中进行简单的 GraphQL 查询

Posted

技术标签:

【中文标题】如何在 JavaScript 中进行简单的 GraphQL 查询【英文标题】:How to do a simple GraphQL query in JavaScript 【发布时间】:2020-05-23 19:51:55 【问题描述】:

如果我使用node-fetchcurl 进行 GraphQL 查询,我会得到预期的结果。例如,如果我有一个带有以下代码的文件 gquery.js

const fetch = require("node-fetch")
fetch('https://api.example.com/graphql', 
  method: 'POST',
  headers: 
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'X-Api-Service-Key': '123456789077',
  ,
  body: JSON.stringify(query: "query($fruitId: String!)  fruit(id: $fruitId)  id, name  ",
  variables:  "fruitId": "ikttwwwbvn7" )
)
  .then(r => r.json())
  .then(data => console.log('data returned:', data));

在我的 Ubuntu 机器上,我只需运行 $node gquery.js 即可返回结果。如果我使用普通卷曲,我也会得到结果,例如:

curl -H 'Content-Type: application/json' -X POST -H "X-Api-Service-Key: 123456789077" https://api.example.com/graphql -d ' "query": "query($fruitId: String!)  fruit(id: $fruitId)  id, name  ", "variables":  "fruitId": "ikttwwwbvn7" '

但是,如果我只是在 Chrome 上使用 fetch,例如:

fetch('https://api.example.com/graphql', 
  method: 'POST',
  headers: 
    'Content-Type': 'application/json',
    'Accept': 'application/json',
    'X-Api-Service-Key': '123456789077',
  ,
  body: JSON.stringify(query: "query($fruitId: String!)  fruit(id: $fruitId)  id, name  ",
  variables:  "fruitId": "ikttwwwbvn7" )
)
  .then(r => r.json())
  .then(data => console.log('data returned:', data));

我收到一个错误:

CORS 策略已阻止从源“chrome-search://local-ntp”获取“https://api.example.com/graphql”的访问权限:对预检请求的响应未通过访问控制检查:没有“访问控制-请求的资源上存在 Allow-Origin' 标头。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。

注意:我的端点实际上是不同的,但除此之外,此示例与我的示例基本相同。

我查看了related question,但答案似乎表明这不能仅在客户端解决。但我可以成功使用curlnode 的事实告诉我,我只是没有正确的代码。

需要明确的是,我并不真正关心fetch。我很乐意使用任何不需要使用 apollo 或 relay 等客户端的独立 javascript 解决方案。

【问题讨论】:

fetch API 正是您所寻找的。但是在浏览器中,您只是受到同源策略的限制,对此您无能为力。 node-fetch 是基于服务器的(因为它是节点)。它不受 CORS 政策的约束,它可以为所欲为。 fetch 相当于fetch 的浏览器。问题是浏览器 JS 受 CORS 策略约束,除了从您必须托管的自己的代理服务器获取之外,无法绕过它。 谢谢,我正在寻找代码解决方案。我知道有像 relay 和 apollo 这样的 Javascript GraphQL 客户端,但我认为必须有一种方法可以在 JavaScript 中构造一个可以在浏览器上运行的简单查询。但如果答案是“这是不可能的,这就是为什么……”,我可以接受。我将更改我的问题以反映我想要实现的目标。 那些库将受到完全相同的限制。您需要修复服务器的 CORS 策略、在您的域上使用代理或其他方式。另外,您的 js 代码运行的环境究竟是什么? “origin 'chrome-search://local-ntp'”看起来很奇怪。 @Nagev“”与您的原始问题不同。你在问什么,如何在浏览器中使用JavaScript 做一个GraphQL 查询请求?或者如何解决您在尝试发出 GraphQL 请求时在浏览器中看到的 CORS 错误? 【参考方案1】:

无法绕过浏览器强制执行的same-origin policy。通过curlnode 发送请求时,您不会遇到同样的问题,因为在这些上下文中未强制执行同源策略。它始终在浏览器中强制执行,除非您 explicitly disable it。不过,防止跨域请求是一种导入安全措施,因此通常不建议禁用它。

像 Apollo 这样的 GraphQL 客户端的工作方式并没有什么神奇之处。他们仍然在后台使用fetch。如果您使用 fetch 遇到了 CORS 问题,那么使用 Apollo 或任何其他基于浏览器的客户端也会遇到同样的问题。如果您使用 Postman 或 Altair 之类的独立客户端,则不会,因为您再次处理的不是浏览器。

正如您链接的帖子中所建议的,这是一个必须在服务器端解决的问题。如果您不向自己的服务器发出请求,唯一可行的解​​决方法是使用代理。您可以使用an existing one 或运行您自己的。

【讨论】:

以上是关于如何在 JavaScript 中进行简单的 GraphQL 查询的主要内容,如果未能解决你的问题,请参考以下文章

灰色关联度分析法(GRA)_python

arcgis api for javascript如何遍历graphics

如何忽略Lua中字符串操作的特殊字符?

如何在Javascript中进行rest API调用[重复]

用Javascript进行一个简单的机器学习小实例

如何在 VueJs 组件中对 oembed javascript 标记进行整数处理?