1

Everything I read says that you can pass a relative url into a fetch call eg

fetch('/path/to/resource/')

but when I do that, I get an "unrecognized url" error. Instead I'm being forced to do an absolute url for my local host, which makes it a pain for my team to use my code eg

fetch('http://123.0.0.44:8000/path/to/resource')

I'm only working in Android currently. Do I need to add the base url to the project or something? Or do I have to fashion a dynamic absolute path by pulling in the base url from somewhere? I'd rather just use the relative path, if that's possible, but I can't find anyone else having the same trouble as I am using it. Seems to "just work" for everyone else.

Brimby
  • 847
  • 8
  • 25

3 Answers3

2

The possible solution is to create a configuration file, that would have f.e. 'SERVER_HOST' variable, that would include 'http://123.0.0.44:8000'. So, after you import the config file you could write something like

fetch( config.SERVER_HOST + '/path/to/resource' )
philippsh
  • 788
  • 9
  • 17
  • That's my localhost ip though. If my other team members were to pull my code, it wouldn't be correctly pointing to their localhost. I'm sure I could look up how to get the server to template its ip onto my files so that I can always have the proper base URL, but I'm mostly curious as to if others are seeing this behavior with fetch in React Native, or if my situation is unique for some reason. – Brimby Dec 06 '16 at 23:48
0

As said on fecebook's official react-native website you should enter URL as ebdpoint. link

philippsh
  • 788
  • 9
  • 17
0

I've just encountered this when making a project that shares code between React Native v0.59.5 and React Native Web v0.11.2. fetch is a global API available in both environments (but admittedly may need polyfilling for the latter if you're targeting very old browsers). Interestingly, React Native's implementation of fetch is identical to the kind that you'd polyfill for web browsers (whatwg-fetch), so their underlying XmlHttpRequest implementation is probably where things differ.

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!"

As I was connecting to localhost over the http:// protocol, I double-checked that my App Transport security was set up correctly (it was).

In the case of React Native, no corresponding request is even shown in the network debugger, so I suspected a security violation. Then I realised that it's quite obvious: on React Native Web, the app is always hosted on the web, so it's natural that fetch() requests are made relative to that domain. But React Native apps are not hosted on a domain.

It looks like React Native's implementation passes the URL onto RCTNetworking.sendRequest(), and then ultimately on to RCTNetworking.mm here, at least for iOS. It ends up as a [NSMutableURLRequest requestWithURL:URL] using an NSURL formed from the dictionary via [RCTConvert NSURL:query[@"url"]]. The implementation of RCTConvert here shows that the NSURL is initialised using the [NSURL URLWithString:path] method with no relativeToURL path, so the URL is relative to nothing (and may well return nil)! So it's no wonder that it fails. It's also clear from the implementation that there's no way in React Native to globally declare a URL base to base such URLs relative to.

There's definitely potential for a Pull Request in here to improve parity between React Native and React Native Web. But until then, something along the lines of phillipsh's solution, wherein you explicitly detail the host domain, will have to do..!

Relevant reading

Jamie Birch
  • 5,839
  • 1
  • 46
  • 60