React-native: Image from url loads with https but fails loading with http

Created on 1 Jul 2016  路  16Comments  路  Source: facebook/react-native

I am trying to display a simple image from an URL in the iOS Simulator. When the URL is a https domain it works fine but when I try loading from a http domain the image is not loaded. Via the inspector you can see that a blank image was created. My code is the following:
render() { return ( <View> <Image source={{uri: 'https://facebook.github.io/react/img/logo_og.png'}} // source={{uri: 'http://facebook.github.io/react/img/logo_og.png'}} style={{width: 400, height: 400}} onLoadStart={() => console.warn('loading started')} onLoad={() => console.warn('loading successful')} onLoadEnd={() => console.warn("loading endet (successful or not")} /> </View> ); }

I already tried:

  • Restarting the packager and the iOS simulator (no change)
  • Reset Contents and Settings of the iOS simulator (no change)
  • Tried several other images via http and https
  • Created new project from scratch via react-native init myurltestproject` and added code from above (still not working for http images)

I am using:

  • react-native-cli: 1.0.0
  • react-native: 0.28.0
  • macOS 10.10.5 (Yosemite)
  • MacBook Pro 13inch early 2015

Side note:
Interestingly when I try to run the exact same code on the simulator but via Deco IDE (Version 1.1.2 (0.7.0)) http and https url are working.

Locked

Most helpful comment

Our is not working with https in Android. Can you please tell us how was your working on Android?

All 16 comments

My first thought would be the new-ish App Transport Security https://ste.vn/2015/06/10/configuring-app-transport-security-ios-9-osx-10-11/

It's kinda weird that it would work with Deco, but I'm also not familiar with what Deco might do under the hood, so YMMV.

@alloy Yes, seems to be an iOS specific problem. I just tried to run the code above in Android and it worked fine for any http and https URL.
Is it possible to get somehow the error message so we can check if it is caused by the App transport security change?
I would be happy to help if I can :)

Seeing as you don't know if this is the issue, that means you have definitely not added any exceptions to your Info.plist file, which means that only HTTPS will work.

The solution is basically to only use HTTPS endpoints. You can add a Info.plist entry to disable the ATS functionality, but it is said that Apple is going to require it for all apps anyways, so you might as well start doing it now.

To be clear, assuming this is ATS, this is not a React Native issue, but iOS in general.

@alloy's analysis sounds right to me. This is not React Native, but rather iOS enforcing HTTPS. And as already mentioned, you can add your endpoints to the whitelist the same way you'd do so for any other iOS app but Apple is going to make ATS mandatory in six months anyway: http://9to5mac.com/2016/06/15/ats-https-ios-apps/.

Ok thanks for the clarification. It is still interesting though that this works when you run it with the Deco IDE. Seems weird to me.

The tutorial is also broken for the IOS simulator, since Rotten tomatoes examples use http

screen shot 2016-07-05 at 6 14 58 pm

They changed the code of the movie example to use a https url now. See this commit: https://github.com/facebook/react-native/pull/367/commits/b00d4b394f590a3d8365d7a63cf5436c499483ec
So now it's working again also for iOS.

Any solution for loading the images over http?

@gitlovenotwar You can add a security exception in Info.plist file.
<key>NSAppTransportSecurity</key> <dict> <key>NSAllowsArbitraryLoads</key> <true/> </dict>

Reference: https://googleadsdeveloper.blogspot.in/2015/08/handling-app-transport-security-in-ios-9.html

Since January 2017, Apple require developers to justify whenever an app allow all unsafe (http) sources using what @shikya wrote.

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>testdomain.com</key>
        <dict>
            <key>NSIncludesSubdomains</key>
            <true/>
            <key>NSExceptionAllowsInsecureHTTPLoads</key>
            <true/>
            <key>NSExceptionRequiresForwardSecrecy</key>
            <true/>
            <key>NSExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSThirdPartyExceptionAllowsInsecureHTTPLoads</key>
            <false/>
            <key>NSThirdPartyExceptionRequiresForwardSecrecy</key>
            <true/>
            <key>NSThirdPartyExceptionMinimumTLSVersion</key>
            <string>TLSv1.2</string>
            <key>NSRequiresCertificateTransparency</key>
            <false/>
        </dict>
    </dict>
</dict>

All keys are optional except for domain.

I tried using https and the images still does not show for whatever reason...

<Image
  style={{ width: 50, height: 50, borderWidth: 1 }}
  source={{
    uri: 'https://icons.iconarchive.com/icons/paomedia/small-n-flat/72/profile-icon.png'
  }}
/>

screen shot 2018-02-14 at 1 31 54 pm

it works on android though. Any ideas?

@aprilmintacpineda Because your URL is https, but your URL does not support https. It is redirecting to HTTP instead.

@shikya aa! I understand now. I didn't consider that one. Thanks.

Our is not working with https in Android. Can you please tell us how was your working on Android?

@aartivaz You should use StackOverflow for this. Make sure you add a sample code too.

Was this page helpful?
0 / 5 - 0 ratings