所以我的graphql api位于https://gpbaculio-tributeapp.herokuapp.com/graphql我配置了上传的标题,如下所示:
const fetchQuery = (operation, variables) => {
return fetch('/graphql', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
body: JSON.stringify({
query: operation.text,
variables,
}),
}).then(response => {
return response.json()
})
}
我已从MDN上读到。
对于没有凭据的请求,服务器可以将“*”指定为 通配符,从而允许任何来源访问资源。
所以我试图在codepen中发布应用程序,这是我的错误:
无法加载https://gpbaculio-tributeapp.herokuapp.com/graphql: 对预检请求的响应未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。来源'https://s.codepen.io'
为什么它告诉我它没有通过'Access-Control-Allow-Origin'标题?
我的标头配置有问题吗?
答案 0 :(得分:1)
您正在请求中设置标头(在客户端中)。需要在服务器端设置Access-Control-Allow-Origin
标头,当您发出请求时,响应应该包含该标头。
此标题背后的原因是并非每个网页都可以查询每个第三方域。能够从请求中设置此标题将失败这一点。
答案 1 :(得分:0)
CORS规范指出,资源请求是使用HTTP OPTIONS请求“预检”的,并且该OPTIONS的回复标头必须包含标头:
Access-Control-Allow-Origin: *
你可以用curl检查它:
$ curl -I -X OPTIONS https://gpbaculio-tributeapp.herokuapp.com/graphql
HTTP/1.1 405 Method Not Allowed
Server: Cowboy
Connection: keep-alive
X-Powered-By: Express
Allow: GET, POST
Content-Type: application/json; charset=utf-8
Content-Length: 97
Date: Sat, 23 Sep 2017 11:24:39 GMT
Via: 1.1 vegur
添加带有所需标头的OPTION处理程序,以便服务器回答:
$ curl -I -X OPTIONS https://example.localhost/
HTTP/1.1 204 No Content
Server: nginx/1.4.7
Date: Sat, 23 Sep 2017 11:27:51 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range
Content-Type: text/plain; charset=utf-8
Content-Length: 0
答案 2 :(得分:0)
问题是浏览器的跨域问题。
Access-Control-Allow-Origin
标头应该由服务器的响应返回,标头表示可以访问API的源域。
客户端的请求通常采用标头Origin
,其值为当前主机地址,例如www.example.com
。
Access-Control-Allow-Origin
的值必须包含值Origin
,表示原点可以访问此API服务。然后浏览器将继续请求。如果没有,浏览器将取消请求。
更多信息,请参阅CORS https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
答案 3 :(得分:0)
尝试在服务器端设置 cors 选项和 Access-Control-Allow-Origin 标头。
const graphQLServer = express();
const corsOptions = {
origin(origin, callback) {
callback(null, true);
},
credentials: true
};
graphQLServer.use(cors(corsOptions));
var allowCrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', '*');
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
next();
}
graphQLServer.use(allowCrossDomain);
这可能对您有所帮助