fetch 永远不会在测试环境中调用 .then 或 .catch
fetch is never calling .then nor .catch in testing environment
我有以下网络组件:
import React, { useCallback, useState } from 'react'
import { ErrorBoundary } from 'react-error-boundary'
import { useFocusEffect } from '@react-navigation/native'
import styled from 'styled-components/native'
import { useEduConnect, useEduConnectClient } from '../../../IdCheckContext'
import { EduConnectErrorBoundary } from '../../../errors/eduConnect/EduConnectErrorBoundary'
import { ErrorTrigger } from '../../../errors/ErrorTrigger'
import { EduConnectError, EduConnectErrors } from '../../../errors/eduConnect'
import { PageWithHeader } from '../../layout/PageWithHeader'
import { IdCardMagnifyingGlassIcon } from '../../icons/IdCardMagnifyingGlass'
import { getSpacing } from '../../../ui/utils'
import { ButtonPrimary, Spacer, Typo } from '../../../ui/components'
import { ColorsEnum } from '../../../theme/colors'
export const EduConnectForm = () => {
const eduConnectClient = useEduConnectClient()
const allowEduConnect = useEduConnect()
const [error, setError] = useState<EduConnectError | null>(allowEduConnect ? null : new EduConnectError(EduConnectErrors.unavailable))
const checkIfEduConnectIsAvailable = useCallback(() => {
if (allowEduConnect === false) {
setError(new EduConnectError(EduConnectErrors.unavailable))
}
}, [allowEduConnect])
const openEduConnect = useCallback(() => {
function setWebView() {
eduConnectClient?.getAccessToken().then((value) => {
console.log('value', value, `${eduConnectClient.getLoginUrl()}?redirect=false`)
const request: RequestInit = {
headers: {
Authorization: `Bearer ${value}`,
} as unknown as Record<string, string>,
mode: 'cors',
credentials: 'include',
}
fetch(`${eduConnectClient.getLoginUrl()}?redirect=false`, request)
.catch((err) => {
console.log(1)
console.error(err)
setError(err)
}) // should be 401 or something, will display default error
.then((response) => {
console.log(JSON.stringify(response))
// @ts-ignore fix response typing
if ('status' in response && response.status === 200) {
const finalURL = response?.headers?.get('educonnect-redirect')
if (finalURL) {
globalThis.window.open(finalURL, '_blank')
}
}
})
})
.catch((err) => {
console.log(1)
console.error(err)
setError(err)
})
}
setWebView()
}, [eduConnectClient])
useFocusEffect(
useCallback(() => {
openEduConnect()
checkIfEduConnectIsAvailable()
}, [checkIfEduConnectIsAvailable, openEduConnect])
)
if (error) {
throw error
}
return (
<ErrorBoundary FallbackComponent={EduConnectErrorBoundary}>
<PageWithHeader
title="Mon identité"
scrollChildren={
<>
<Center>
<IdCardMagnifyingGlassIcon size={getSpacing(47)} />
</Center>
<Typo.ButtonText color={ColorsEnum.GREY_DARK}>{`Identification`}</Typo.ButtonText>
<Spacer.Column numberOfSpaces={4} />
<Typo.Body color={ColorsEnum.GREY_DARK}>
{`Pour procéder à ton identification, nous allons te demander de te connecter à ÉduConnect. Muni toi de ton identifiant et de ton mot de passe ÉduConnect. Dès que tu as bien complété le parcours, reviens sur ce site pour terminer ton inscription et découvrir toutes les offres du pass Culture !`}
</Typo.Body>
<Spacer.Column numberOfSpaces={8} />
</>
}
bottomChildren={
<ButtonPrimary
title={`Ouvrir un onglet ÉduConnect`}
onPress={openEduConnect}
/>
}
/>
<ErrorTrigger error={error} />
</ErrorBoundary>
)
}
const Center = styled.View({
alignSelf: 'center',
})
在本地,fetch
请求成功并打开一个新选项卡。在测试环境中,它从不调用 .catch
或 .then
。我希望至少调用两者之一。
这是我在 testing
环境中的网络开发人员选项卡:
这是我在 testing
环境中的控制台开发人员选项卡:
知道这里出了什么问题吗?
这是由于缺少允许客户端读取 header 以防止 XSS 攻击所必需的 Access-Control-Expose-Headers
:
For clients to be able to access other headers, the server must list them using the Access-Control-Expose-Headers
header.
mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers
我有以下网络组件:
import React, { useCallback, useState } from 'react'
import { ErrorBoundary } from 'react-error-boundary'
import { useFocusEffect } from '@react-navigation/native'
import styled from 'styled-components/native'
import { useEduConnect, useEduConnectClient } from '../../../IdCheckContext'
import { EduConnectErrorBoundary } from '../../../errors/eduConnect/EduConnectErrorBoundary'
import { ErrorTrigger } from '../../../errors/ErrorTrigger'
import { EduConnectError, EduConnectErrors } from '../../../errors/eduConnect'
import { PageWithHeader } from '../../layout/PageWithHeader'
import { IdCardMagnifyingGlassIcon } from '../../icons/IdCardMagnifyingGlass'
import { getSpacing } from '../../../ui/utils'
import { ButtonPrimary, Spacer, Typo } from '../../../ui/components'
import { ColorsEnum } from '../../../theme/colors'
export const EduConnectForm = () => {
const eduConnectClient = useEduConnectClient()
const allowEduConnect = useEduConnect()
const [error, setError] = useState<EduConnectError | null>(allowEduConnect ? null : new EduConnectError(EduConnectErrors.unavailable))
const checkIfEduConnectIsAvailable = useCallback(() => {
if (allowEduConnect === false) {
setError(new EduConnectError(EduConnectErrors.unavailable))
}
}, [allowEduConnect])
const openEduConnect = useCallback(() => {
function setWebView() {
eduConnectClient?.getAccessToken().then((value) => {
console.log('value', value, `${eduConnectClient.getLoginUrl()}?redirect=false`)
const request: RequestInit = {
headers: {
Authorization: `Bearer ${value}`,
} as unknown as Record<string, string>,
mode: 'cors',
credentials: 'include',
}
fetch(`${eduConnectClient.getLoginUrl()}?redirect=false`, request)
.catch((err) => {
console.log(1)
console.error(err)
setError(err)
}) // should be 401 or something, will display default error
.then((response) => {
console.log(JSON.stringify(response))
// @ts-ignore fix response typing
if ('status' in response && response.status === 200) {
const finalURL = response?.headers?.get('educonnect-redirect')
if (finalURL) {
globalThis.window.open(finalURL, '_blank')
}
}
})
})
.catch((err) => {
console.log(1)
console.error(err)
setError(err)
})
}
setWebView()
}, [eduConnectClient])
useFocusEffect(
useCallback(() => {
openEduConnect()
checkIfEduConnectIsAvailable()
}, [checkIfEduConnectIsAvailable, openEduConnect])
)
if (error) {
throw error
}
return (
<ErrorBoundary FallbackComponent={EduConnectErrorBoundary}>
<PageWithHeader
title="Mon identité"
scrollChildren={
<>
<Center>
<IdCardMagnifyingGlassIcon size={getSpacing(47)} />
</Center>
<Typo.ButtonText color={ColorsEnum.GREY_DARK}>{`Identification`}</Typo.ButtonText>
<Spacer.Column numberOfSpaces={4} />
<Typo.Body color={ColorsEnum.GREY_DARK}>
{`Pour procéder à ton identification, nous allons te demander de te connecter à ÉduConnect. Muni toi de ton identifiant et de ton mot de passe ÉduConnect. Dès que tu as bien complété le parcours, reviens sur ce site pour terminer ton inscription et découvrir toutes les offres du pass Culture !`}
</Typo.Body>
<Spacer.Column numberOfSpaces={8} />
</>
}
bottomChildren={
<ButtonPrimary
title={`Ouvrir un onglet ÉduConnect`}
onPress={openEduConnect}
/>
}
/>
<ErrorTrigger error={error} />
</ErrorBoundary>
)
}
const Center = styled.View({
alignSelf: 'center',
})
在本地,fetch
请求成功并打开一个新选项卡。在测试环境中,它从不调用 .catch
或 .then
。我希望至少调用两者之一。
这是我在 testing
环境中的网络开发人员选项卡:
这是我在 testing
环境中的控制台开发人员选项卡:
知道这里出了什么问题吗?
这是由于缺少允许客户端读取 header 以防止 XSS 攻击所必需的 Access-Control-Expose-Headers
:
For clients to be able to access other headers, the server must list them using the
Access-Control-Expose-Headers
header.
mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers