CORS 阻止 GraphQL Yoga 中的突变

Posted

技术标签:

【中文标题】CORS 阻止 GraphQL Yoga 中的突变【英文标题】:CORS blocks mutation in GraphQL Yoga 【发布时间】:2019-05-16 10:52:14 【问题描述】:

我在这里使用的是 graphql prisma 后端和 graphql yoga express 服务器。在前端,我试图调用一个注销突变,但它被 CORS 策略阻止。尽管我在我的 graphql 瑜伽服务器中添加了 cors 设置,但我一直收到此错误。 GraphQL 查询工作正常,但突变被阻止。我的前端 URL 是“http://localhost:7777”,瑜伽服务器在“http://localhost:4444/”运行。错误是:

Access to fetch at 'http://localhost:4444/' from origin 'http://localhost:7777' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

[Network error]: TypeError: Failed to fetch

GraphQL Yoga Server Cors 配置:

server.start(

    cors: 
        credentials: true,
        origin: [process.env.FRONTEND_URL],
    ,
,
deets => 
    console.log(
        `Server is now running on port http://localhost:$deets.port`
    );

);

变异:

// import React,  Component  from 'react';
import  Mutation  from 'react-apollo';
import styled from 'styled-components';
import gql from 'graphql-tag';
import  CURRENT_USER_QUERY  from './User';
import  log  from 'util';

const SIGN_OUT_MUTATION = gql`
mutation SIGN_OUT_MUTATION 
    signout 
        message
    

`;

const SignOutBtn = styled.button`
color: $props => props.theme.textMedium;
padding: 10px;
margin-right: 20px;
text-align: center;
font-family: garamond-light;
border: 1px solid $props => props.theme.textMedium;
border-radius: 5px;
transition: background-color 0.5s ease;
transition: color 0.5s ease;
:hover 
    background: $props => props.theme.textMedium;
    color: $props => props.theme.white;

`;

const Signout = props => (
<Mutation
    mutation=SIGN_OUT_MUTATION
    refetchQueries=[ query: CURRENT_USER_QUERY ]
>
    signout => (
        <SignOutBtn
            onClick=() => 
                console.log("comes here")
                signout();
            
        >
            Sign Out
        </SignOutBtn>
    )
</Mutation>
);
export default Signout;

请告诉我我在这里做错了什么。提前致谢。

【问题讨论】:

我看不出您共享的代码有什么问题。您能否提供一个最低限度的可重现存储库供我们进行更多调查? @Errorname 感谢您的帮助,您可以找到 repo here。回购将没有环境文件。如果您需要这些,请告诉我。 感谢您提供链接,但要分析的文件太多。您能否创建一个仅包含重现问题所需文件的存储库? 【参考方案1】:

服务器应用程序必须在响应头中添加Access-Control-Allow-Origin: YOUR_DOMAIN,浏览器不会抱怨。

您可以使用中间件来实现它。

app.use(function(req, res, next) 
  res.header("Access-Control-Allow-Origin", "YOUR-DOMAIN"); // update to match the domain you will make the request from
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
);

const cors =  require('cors')
const corsOptions = 
    origin: [
        
        "http://YOUR-DOMAIN"
    ],
    credentials: true

app.use(cors(corsOptions))

等一下!!我已经完成了这些步骤,但问题仍然存在;(

如果经过这些步骤后问题仍然存在。

那是因为响应损坏

可能是您的服务器在发送响应时抛出异常,或者它重新启动并且响应未完全发送到客户端。或者您的 ISP 或 *** 可能存在一些问题,阻止了某些请求。 :)

【讨论】:

【参考方案2】:

添加这个中间件对我有帮助:

server.express.use((req, res, next) => 
  res.header('Access-Control-Allow-Credentials', true)
  next()
)

【讨论】:

【参考方案3】:

我遇到了同样的问题,用这个解决了

server.start(
  
    cors: 
      credentials: true,
      origin: [process.env.FRONTEND_URL],
      methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
      preflightContinue: false,
      optionsSuccessStatus: 204
    
  ,
  server => 
    console.log(`Server is running on http://localhost/$server.port`);
  
);

【讨论】:

【参考方案4】:

我必须做的是向原点传递一个字符串值数组。以及在 heroku 中设置新的原点 PAST_FRONTEND_URL

server.start(
  
    cors: 
      credentials: true,
      origin: [process.env.FRONTEND_URL, process.env.PAST_FRONTEND_URL],
    ,
  ,
  deets => 
    console.log(`Server is now running on port http://localhost:$deets.port`);
  
);

【讨论】:

【参考方案5】:

该问题的解决方案是编写一个中间件来设置适当的响应标头,以便获取不会失败。

server.express.use(function(req, res, next) 
  res.header('Access-Control-Allow-Origin', 'http://localhost:7777');
  res.header(
    'Access-Control-Allow-Headers',
    'Origin, X-Requested-With, Content-Type, Accept'
  );
  next();
);

以上是用于解决问题的yoga express服务器中间件。

【讨论】:

您是否在服务器上保留了cors: credentials: true,origin: process.env.FRONTEND_URL,, @ChanceSmith 是的,我试过了,但它不适合我。我也在问题中发布了相同的配置。如果我做错了什么,请告诉我。 抱歉,我遇到了同样的问题,但现在想知道您是否将那个对象留在了里面。 ?‍♂️

以上是关于CORS 阻止 GraphQL Yoga 中的突变的主要内容,如果未能解决你的问题,请参考以下文章

使用来自突变解析器的 GraphQL Yoga 响应自定义 HTTP 代码

Prisma graphql updateNode 突变

定义在graphql瑜伽的突变说法

注册突变时的 Prisma graphql 错误

无法在 React 中使用 GraphQL 查询 - 已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头

graphql-yoga - GraphQL 解析器参数在哪里定义和记录?