Apollo-link-rest: "Cabeçalhos não estão definidos" ocorrem ao usar apollo-link-rest no mini programa weixin

Criado em 16 jul. 2019  ·  25Comentários  ·  Fonte: apollographql/apollo-link-rest

  • [x] tem-reprodução

Quando tentamos usar apollo-link-rest no mini programa weixin, encontramos um problema que gerou um erro como abaixo:

 Headers is not defined 
 ReferenceError: Headers is not defined

Como eu encontrei o código-fonte em RestLink.ts, ele tenta encontrar os cabeçalhos, mas absolutamente, não há cabeçalhos no ambiente weixin, então alguém pode ajudar a fornecer algum hack ou soluções para resolver esse problema? Agradeço muito se você puder ajudar, obrigado.

help wanted 🛠 question❔

Comentários muito úteis

Aqui está o que acabou funcionando para mim:

import clientFetch from 'unfetch';
import serverFetch, { Headers as ServerHeaders } from 'node-fetch';

const client = typeof document !== 'undefined';
global.Headers = client ? global.Headers : ServerHeaders;
const customFetch = client ? clientFetch : serverFetch;

const acmeLink = new JsonApiLink({
  …
  credentials: 'same-origin',
  customFetch,
});

Todos 25 comentários

Olá @ Janice1114 , não estou familiarizado com o weixin, mas talvez você possa usar um Headers Polyfill?

Freqüentemente, se os cabeçalhos não estiverem disponíveis, a busca também estará indisponível. Portanto, um polyfill que pode funcionar para ambos é este: https://github.com/bitinn/node-fetch

Olá @fbartho , obrigado pela sua resposta rápida. Tentei usar o polyfill para habilitar a busca de cabeçalhos, mas ainda obtenho os erros.

E descobri que em weixin, ele usa wx.request para a busca, que não oferece suporte a variáveis ​​relacionadas à janela, então temo que o polyfill não funcione.

E posso saber se haveria algum hack ou implementações para ajudar a pular o loop de cabeçalhos no código-fonte do apollo-link-rest? Ou você poderia fornecer algumas opções personalizadas para atender a diferentes cenários?

Você pode usar o parâmetro customFetch para ApolloLinkRest a fim de fornecer uma função de invólucro, esta função de invólucro pode pegar os cabeçalhos baseados em janela do Polyfill e achatá-los em um Hash de objeto tradicional.

Algo como o seguinte (não testado, escrito em meu navegador):

function customFetch(url, options) {
   const headers = options.headers.entries().reduce((accumulator, h) => { accumulator[h[0]] = h[1];  return accumulator;}, {})
   return fetch(url, {…options, headers});
}
// Elsewhere: new RestLink({ customFetch, ...

Muito obrigado por sua resposta gentil, tentarei usar este polyfill no desenvolvimento de weixin.

E conforme leio o código-fonte em RestLink.ts, ele tentará acessar os cabeçalhos, que não estão disponíveis no weixin. Ele poderia atribuir as variáveis ​​em global .

Então, eu me pergunto se alguma configuração personalizada ou substituída pode ser aplicada durante o processo do construtor RestLink?

Atenciosamente novamente por suas dicas tão maravilhosas.

Olá @fbartho , para corrigir esse problema no weixin e no navegador especial relacionado, criei um PR conforme abaixo:
Correção de problema de cabeçalhos

Você poderia ajudar e revisar se o código PR está disponível para mesclar com o mestre
Muito obrigado e muito obrigado se isso pudesse ajudar.

Eu tenho o mesmo problema em "next": "^9.0.3"

Também estou tendo esse problema com a próxima versão ^8.1.0 . Para minha API gráfica eu uso isomorphic-unfetch , versão ^3.0.0 para polyfill assim:

import fetch from 'isomorphic-unfetch'
const graphLink = createHttpLink({ uri, fetch })

Mas usar o mesmo pacote para polyfill com o link restante não funcionou:

const restLink = new RestLink({
  uri,
  customFetch: fetch,
})

Eu também tentei node-fetch usando seu método customFetch:

import fetch from 'node-fetch'

function customFetch(url, options) {
  const headers = options.headers.entries().reduce((accumulator, h) => {
    accumulator[h[0]] = h[1]
    return accumulator
  }, {})
  return fetch(url, { ...options, headers })
}

const restLink = new RestLink({
  uri: CONTENTFUL_CONTENT_DELIVERY_API,
  customFetch,
})

Em ambos os casos, obtive ReferenceError: Headers is not defined ao executar em seguida no modo de desenvolvimento.

Adorei a ideia aqui, adoraria se você pudesse fornecer alguma orientação sobre como implementar em ambientes de servidor. Obrigado!

Você pode preencher a API de cabeçalhos enquanto ainda usa sua API customFetch!

Deixe-me saber se você gostaria de algum código de amostra lá, mas tenho certeza de que isso é possível sem muito trabalho. Não estou no meu computador neste minuto.

@fbartho Algum código de amostra seria ótimo quando você tivesse uma chance! Eu tentei, mas não tive sucesso. Obrigado!

import * as Polyfillheaders from 'fetch-headers'
import fetch from 'isomorphic-unfetch'

// hook in the Headers polyfill for your environment!
global.Headers = global.Headers || Polyfillheaders;

function customFetch(url, options) {
  const headers = options.headers.entries().reduce((accumulator, h) => {
    accumulator[h[0]] = h[1]
    return accumulator
  }, {})
  return fetch(url, { ...options, headers })
}

const restLink = new RestLink({
  uri: CONTENTFUL_CONTENT_DELIVERY_API,
  customFetch,
})

Algo como o acima pode resolver o problema @ 2wheelcoder

Obrigado! Vou relatar de volta aqui depois que eu tiver a chance de tentar isso.

@fbartho Hi! Estou enfrentando esse problema no ios 9.3.5. Tentei importar o polyfill fetch-headers mas não funcionou.
Descobri que a instância do cabeçalho de fetch-headers não tem o método forEach (veja abaixo).
image

Existe alguma outra solução?

@fbartho Hi! Estou enfrentando esse problema no ios 9.3.5. Tentei importar o polyfill fetch-headers mas não funcionou.
Descobri que a instância do cabeçalho de fetch-headers não tem o método forEach (veja abaixo).
image

Existe alguma outra solução?

Resolvi esse problema usando o fetch polyfill.

Vou fechar isso, porque acredito que podemos resolver isso com um polyfill no lado do aplicativo, e não queremos tornar o polyfill uma dependência deste repositório.

Não consegui resolver isso com um polyfill. Eu tentei isomorphic-fetch, isomorphic-unfetch, fetch-headers, etc. e sempre acabei com um problema sobre current.forEach não ser definido ou TypeError: Right-hand side of 'instanceof' is not an object . Qualquer ajuda?

@VinSpee Você já tentou este fetch polyfill.

@lintuming sim, mas não funciona no servidor.

@VinSpee Talvez você possa usar isso , parece que eles têm o método forEach .
image
Espero que este trabalho.

@lintuming obrigado por tentar ajudar. Com esse, eu recebo:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

parece ser uma teia emaranhada de problemas 🤣

@VinSpee Desculpe, não tenho ideia de por que isso aconteceu. Mas acho que isso pode ajudar:
https://stackoverflow.com/questions/7042340/error-cant-set-headers-after-they-are-sent-to-the-client

Aqui está o que acabou funcionando para mim:

import clientFetch from 'unfetch';
import serverFetch, { Headers as ServerHeaders } from 'node-fetch';

const client = typeof document !== 'undefined';
global.Headers = client ? global.Headers : ServerHeaders;
const customFetch = client ? clientFetch : serverFetch;

const acmeLink = new JsonApiLink({
  …
  credentials: 'same-origin',
  customFetch,
});

@VinSpee, estou enfrentando o mesmo problema e tentei consertar esse problema com a sua solução, mas não consegui.
Você pode compartilhar seu código de trabalho

Obrigado @VinSpee — isso era exatamente o que eu precisava

Consegui corrigir esse problema usando a busca personalizada

import fetch from "isomorphic-fetch"

const restLink = new RestLink({
  uri: "https://...",
  customFetch: fetch,
  headers: {
    "Content-Type": "application/json",
  },
})

A solução da @VinSpee funcionou para mim também para um aplicativo Gatsby JS.

Esta página foi útil?
0 / 5 - 0 avaliações