我刚刚在制作一个在 React Nativev0.59.5
和 React Native Web之间共享代码的项目时遇到了这个问题v0.11.2
。fetch
是在两种环境中都可用的全局 API(但如果您的目标是非常旧的浏览器,则可能需要对后者进行 polyfill)。有趣的是,React Native 的 fetch 实现与您为 web 浏览器 ( ) 的 polyfill 实现是相同whatwg-fetch
的,因此它们的底层XmlHttpRequest实现可能是不同的地方。
fetch("some/relative/resource.txt")
.then((response) => { console.log("Responded!"); })
.catch(console.error);
// On React Native, logs the error "Network request failed".
// On React Native Web, logs "Responded!"
当我通过协议连接到 localhost 时http://
,我仔细检查了我的应用程序传输安全设置是否正确(确实如此)。
在 React Native 的情况下,甚至在网络调试器中都没有显示相应的请求,所以我怀疑存在安全违规。然后我意识到这很明显:在 React Native Web 上,应用程序始终托管在 Web 上,因此fetch()
请求是相对于该域发出的,这是很自然的。但是 React Native 应用程序并不托管在域上。
看起来 React Native 的实现将 URL 传递到 RCTNetworking.sendRequest(),然后最终传递到RCTNetworking.mm
here,至少对于 iOS 而言。它最终作为[NSMutableURLRequest requestWithURL:URL]
使用从字典通过 NSURL 形成的 NSURL [RCTConvert NSURL:query[@"url"]]
。这里RCTConvert 的实现表明 NSURL 是使用[NSURL URLWithString:path]
没有relativeToURL
路径的方法初始化的,所以 URL 是相对于空的(并且很可能返回nil
)!所以难怪它失败了。从实现中也可以清楚地看出,React Native 中没有办法全局声明一个 URL 基础来作为此类 URL 的相对基础。
这里肯定有一个 Pull Request 的潜力来改善 React Native 和 React Native Web 之间的平衡。但在此之前,必须按照 phillipsh 的解决方案(在其中明确详细说明主机域)做一些事情......!
相关阅读