<p>apollo-link-http 不尊重 GET 方法覆盖</p>

创建于 2017-11-12  ·  20评论  ·  资料来源: apollographql/apollo-link

根据文档fetchOptions选项允许我们将请求的方法设置为GET 。 我希望这样做之后,查询将作为查询字符串参数而不是请求正文包含在内; 如果您尝试使用正文发出 GET 请求,Chrome 会抛出错误。

预期结果:
如果请求方法是 GET,则应构造查询字符串。

实际结果:
使用请求正文。

如何重现问题:

client.query({
  context: {
    fetchOptions: {
      method: 'GET',
    },
  },
  query: QUERY,
  variables: { query },
})
enhancement

最有用的评论

@szdc @Outlaw11A @arackaf这里是如何做到的:

const customFetch = (uri, options) => {
  const { body, ...newOptions } = options;
  const queryString = objectToQuery(JSON.parse(body));
  requestedString = uri + queryString;
  return fetch(requestedString, newOptions);
};
const link = createHttpLink({
  uri: "data",
  fetchOptions: { method: "GET" },
  fetch: customFetch
});

所有20条评论

@szdc是的,这绝对行不通! 你愿意添加它吗? 像https://github.com/apollographql/apollo-link/issues/257这样的东西也可能是一个很好的解决方案,也可以在发送之前转换请求?

cc @arackaf @outlaw11a @puttyman都对此感兴趣! 应该是一个非常小的变化添加!

如果没有其他人想要,我会添加它。

@szdc @arackaf所以事实证明这已经是可能的了! 我将很快推出一个测试和文档,展示如何在没有内部更改的情况下完成

@szdc @Outlaw11A @arackaf这里是如何做到的:

const customFetch = (uri, options) => {
  const { body, ...newOptions } = options;
  const queryString = objectToQuery(JSON.parse(body));
  requestedString = uri + queryString;
  return fetch(requestedString, newOptions);
};
const link = createHttpLink({
  uri: "data",
  fetchOptions: { method: "GET" },
  fetch: customFetch
});

@jbaxleyiii看起来棒极了! 只是好奇 objectToQuery 是从哪里来的? npm 上有 util 吗? 我想如果需要的话就可以很容易地推出自己的 - 基本上将 Object.keys 映射到

escapeUriComponnt(`${k}=${obj[k]}`).join("&");

或类似的东西

https://www.apollographql.com/docs/link/links/http.html#Sending -GET-requests-custom-fetching

@arackaf见评论:

// turn the object into a query string, try object-to-querystring package

https://github.com/Cyber​​lane/object-to-querystring

@jbaxleyiii有效! 太奇妙了!

我只是有一个问题。

创建的查询字符串:

http://localhost/graphql?operationName=AllPlayersQuery&variables=%5Bobject%20Object%5D&query=query%20All...

包含这个: variables=%5Bobject%20Object%5D这是一个问题。

如何解决这个问题?

这看起来像标准的 URI 序列化 - 不要认为你可以避免它 - 为什么会出现问题?

标准 URI? 这个: %5Bobject%20Object%5D

encodeURIComponent('books(title:"Hello World"){Book{title}}')

books(title%3A%22Hello%20World%22)%7BBook%7Btitle%7D%7D

我在 Apollo 中的查询是:

query AllPlayers {
  players {
    id
    name
    surname
}

所以我遇到了[Object object]变量为空的问题,@jbaxleyiii 发布了代码。

这是一个准系统反应应用程序(使用 create-react-app 创建),它通过 GET 获取并工作 - 请参阅index.jshttps :

@johnunclesam显然variables在编码之前没有序列化。 我只是通过添加条件JSON.stringify来调整我的自定义 fetch 方法(从示例 repo 中获得):

const customFetch = (uri, options) => {
  const {body, ...newOptions} = options;
  const parsedBody = JSON.parse(body);
  const command = omitBy(parsedBody, isEmpty);

  if (command.variables) {
    command.variables = JSON.stringify(command.variables);
  }

  const requestedString = uri + '?' + queryString.stringify(command);

  return fetch(requestedString, newOptions);
};

那么useGETForQueries有什么用呢? 为什么useGETForQueries=true时未内置自定义提取?
如何区分查询和变异? 我只想使用 GET 进行查询(用于 DNS 缓存)。

这是一个早于 useGETForQueries 的旧问题,在https://github.com/apollographql/apollo-link/pull/510修复此问题后添加了一点

嗯, useGETForQueries 似乎不起作用。

特别是在这条线上,似乎有一个错误:

https://github.com/apollographql/apollo-link/blob/f94b1c6b984619ec1ef68cca3224be788ea140e4/packages/apollo-link-http/src/httpLink.ts#L41

let {
    uri = '/graphql',
    // use default global fetch if nothing passed in
    fetch: fetcher,
    includeExtensions,
    useGETForQueries,
    ...requestOptions
  } = linkOptions;

应该是这样的:

let {
    uri = '/graphql',
    // use default global fetch if nothing passed in
    fetch: fetcher,
    includeExtensions,
    fetchOptions,
    ...requestOptions
  } = linkOptions;

let {
  useGETForQueries
} = fetchOptions;

是什么让你这么说? 你怎么称呼createHttpLink

我上面的观察是通过调试器逐步执行代码,但我必须重新做才能重现。

我们最终确定的代码是这样的:

import omitBy from 'lodash.omitby';
import isEmpty from 'lodash.isempty';

const graphQLUrl = 'http://the.server.com/graphql';

const customFetch = (uri, options) => {
  const { body, credentials, headers, ...newOptions } = options;
  let fetchUri = uri;
  if (body) {
    const parsedBody = JSON.parse(body);
    const command = omitBy(parsedBody, isEmpty);
    fetchUri = uri + "?" + queryString.stringify(command);
  }
  return fetch(fetchUri, newOptions);
};

const link = createHttpLink({
  uri: graphQLUrl,
  fetchOptions: { method: "GET" },
  fetch: customFetch
});

我想我的问题是,如果您在fetchOptions useGETForQueries内传递createHttpLink内传递,那么这将是您会观察到的行为,但也不会是API 是如何工作的。 我建议再试一次!

此页面是否有帮助?
0 / 5 - 0 等级