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.
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).
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 defetch-headers
não tem o métodoforEach
(veja abaixo).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
.
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.
Comentários muito úteis
Aqui está o que acabou funcionando para mim: