javascript - 如何在 JavaScript 中进行简单的 GraphQL 查询
问题描述
如果我使用 e 进行 GraphQL 查询,node-fetch
或者curl
我得到预期的结果。例如,如果我有一个包含以下代码的文件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 ”获取:对预检请求的响应未通过访问控制检查:否请求的资源上存在“Access-Control-Allow-Origin”标头。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。
注意:我的端点实际上是不同的,但除此之外,此示例与我的示例基本相同。
我看了一个相关的问题,但答案似乎表明这不能仅在客户端解决。curl
但我可以使用并成功的事实node
告诉我,我只是没有正确的代码。
说清楚,我真的不在乎fetch
。我很乐意使用任何不需要使用像 apollo 或 relay 这样的客户端的独立 Javascript 解决方案。
解决方案
没有办法绕过浏览器强制执行的同源策略。通过发送请求时您不会遇到相同的问题,curl
或者node
因为在这些上下文中未强制执行同源策略。除非您明确禁用它,否则它始终在浏览器中强制执行。但是,防止跨域请求是一种导入安全措施,因此通常不建议禁用它。
像 Apollo 这样的 GraphQL 客户端的工作方式并没有什么神奇之处。他们仍然fetch
在引擎盖下使用。如果您在使用 fetch 时遇到了 CORS 问题,那么您会在使用 Apollo 或任何其他基于浏览器的客户端时遇到同样的问题。如果您使用 Postman 或 Altair 之类的独立客户端,则不会,因为您再次处理的不是浏览器。
正如您链接的帖子中所建议的那样,这是一个必须在服务器端解决的问题。如果您不向自己的服务器发出请求,唯一可行的解决方法是使用代理。您可以使用现有的或运行自己的。
推荐阅读
- visual-studio - 如何转换为字符串选项
- asp.net - 如何解决 ASP.Net 中的“加载报告失败”?
- java - 为什么 toHexString 有可变长度?
- python - “模块”对象不可调用,但我已经导入了正确的包
- php - “创建表”有时在 PHPUnit 数据库查询中失败
- webpack - 笑话报道未知
- c - a C program that reads a sequence of numbers and display a message
- php - AngularJS Image Load with PHP
- html - How can i retain my data after refreshing?
- python - 对象是 Python 2.X 中类型的子类吗?