facebook / react-native

A framework for building native applications using React
https://reactnative.dev
MIT License
119.54k stars 24.37k forks source link

ImageSource in Image doesn't send headers #33131

Open ash-williams opened 2 years ago

ash-williams commented 2 years ago

Description

According to the docs, the ImageSource prop in the Image component should allow for sending headers like this:

<Image
    source={{uri: "http://myimage.com", headers: {"Authorization":token}}}
/>

However, the headers aren't sent in any request.

Version

0.64.3

Output of npx react-native info

System: OS: Windows 10 10.0.19042 CPU: (8) x64 Intel(R) Core(TM) i7-8550U CPU @ 1.80GHz Memory: 2.02 GB / 15.85 GB Binaries: Node: 16.13.2 - C:\Program Files\nodejs\node.EXE Yarn: Not Found npm: 8.1.2 - C:\Program Files\nodejs\npm.CMD Watchman: Not Found SDKs: Android SDK: API Levels: 27, 28, 29 Build Tools: 27.0.3, 28.0.3, 29.0.2 System Images: android-24 | Google Play Intel x86 Atom, android-27 | Google APIs Intel x86 Atom, android-28 | China version of Wear OS Intel x86 Atom, android-28 | Google APIs Intel x86 Atom, android-29 | Google Play Intel x86 Atom Android NDK: Not Found Windows SDK: Not Found IDEs: Android Studio: Version 3.5.0.0 AI-191.8026.42.35.6010548 Visual Studio: Not Found Languages: Java: 11.0.11 - C:\Program Files\AdoptOpenJDK\jdk-11.0.11.9-hotspot\bin\javac.EXE npmPackages: @react-native-community/cli: Not Found react: 17.0.1 => 17.0.1 react-native: 0.64.3 => 0.64.3 react-native-windows: Not Found npmGlobalPackages: react-native: Not Found

Steps to reproduce

  1. Create a project (I've been using Expo but don't see how that would be an issue)
  2. Import image from 'react-native'
  3. Try sending any header e.g.: <Image source={{ uri: "url to any image", headers: { "Content-Type": "image/jpeg", "X-Authorization": "thisismyauthtoken" } }} />
  4. Inspect the HTTP request, no headers are sent (I'm running in browser and using Chrome dev tools to inspect HTTP)

Snack, code example, screenshot, or link to a repository

image image image

raarts commented 2 years ago

I am experiencing the exact same problem.

Tran-Minh23 commented 2 years ago

Any solution here guys? I'm facing the same problem. The header in Image acting really weird on Android, but on IOS everything is still smooth

ash-williams commented 2 years ago

I was teaching a University unit when I posted the issue. The workaround we had to go with was to send a regular GET request with the headers to get the image, convert the response to a base64 string, and then use that string as the source to the Image component.

It works fine as a solution, but this issue is still valid as the component doesnt work as the documentation says it should.

Tran-Minh23 commented 2 years ago

I was teaching a University unit when I posted the issue. The workaround we had to go with was to send a regular GET request with the headers to get the image, convert the response to a base64 string, and then use that string as the source to the Image component.

It works fine as a solution, but this issue is still valid as the component doesnt work as the documentation says it should.

Thank you. Seems like it's a well-known bug, I found another topic of this on 2019 (https://github.com/facebook/react-native/issues/25945).

revitteth commented 2 years ago

Is there any progress on this one? It's a bit of a painful blocker unless we send auth material via query string...

NilsBaumgartner1994 commented 1 year ago

Please fix this

Youness-ben commented 1 year ago

Is this still not fixed or are we missing somthing ? the exact same thing is happening to me.

lunaleaps commented 1 year ago

Thanks for reporting! Is there anyway we can narrow this bug -- is there a particular platform this is happening on?

raarts commented 1 year ago

I experienced it on iOS, but I think the original bug poster provided enough information.

blazejczyk commented 1 year ago

I can confirm the headers are still not sent. Here's how I solved this in my app (I used Avatar component from the UI Kitten library but it's actually a small wrapper for the native Image so it's the same situation).

import { useState, useCallback, useEffect } from 'react';
import { ImageSourcePropType } from 'react-native/Libraries/Image/Image';
import { Avatar } from '@ui-kitten/components';
import { EvaSize } from '@ui-kitten/components/devsupport';

import { authorizationHeaders } from '../services/apiSvc';

type TPhotoProps = {
  src: string;
  size?: EvaSize;
};

export default function Photo({ src, size }: TPhotoProps) {
  const [source, setSource] = useState<ImageSourcePropType | undefined>(undefined);

  const load = useCallback(async () => {
    try {
      const response = await fetch(src, { headers: authorizationHeaders });
      const blob = await response.blob();
      const reader = new FileReader();
      reader.readAsDataURL(blob);
      reader.onloadend = () => setSource({ uri: reader.result as string });
    } catch (err) {
      // file loading failed
      setSource(require('../../assets/images/fallback-avatar.png'));
    }
  }, [src]);

  useEffect(() => {
    load();
  }, [load]);

  return (
    <Avatar source={source} size={size} />
  );
}
delimy commented 9 months ago

Happens to me on ios if newArch is on, haven't check Android. And it's clearly not implemented: https://github.com/facebook/react-native/blob/main/packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImagePrimitivesConversions.h#L110 That todo's been there for 6 years now. Works if disable newArch.

ignaciosantise commented 9 months ago

+1 on iOS with new arch

karimb11 commented 9 months ago

This basic feature is very useful to handle authenticated images, much efficient then building a base64 URL, especially in list views. Please consider adding it, it seems like a quick win.

NilsBaumgartner1994 commented 9 months ago

Also from a security aspect this is important because some websites allow to sent the authentication in the url as „?bearer=…“. When doing this and saving the image the token gets saved too as file name.

the adding of headers is therefore essential

Martin2037 commented 8 months ago

same issue

Octaney commented 8 months ago

Same here on Android. It worked for me in version 0.68.2, but after upgrading to 0.73.4 all the images disappeared! I quickly need to update the app in the stores, because of new regulations... help! :(

Update: If you are using Expo, there is a package called "expo-image", that works with headers. For non Expo users, you could try "react-native-fast-image".

rabbitmouse commented 7 months ago

Has this bug been fixed? I have an issue with the image in this link https://github.com/WalletConnect/web3modal-react-native/issues/137#issuecomment-1952502108

In the new architecture, when using modal, the components in the modal will flash first and then appear.

ben-snaize-fg commented 7 months ago

After a fix for this too. Our UAT env's are closed behind headers, so we can't get images working properly in some cases.

0xBlitzmachine commented 7 months ago

Same issue over here .. header is just not working. For those who still come here and read this: Use Expo's Image Component for now .. it is the same component almost and the header works there if youre lazy converting the image to base64.

nghieptd commented 3 months ago

I had this issue when upgrading from 0.67.5 to 0.74.4. I found out that if we have this line: Fresco.initialize(this) then it might cause double initialization (the warning about it pops up in the logcat), which somehow override the React Native image fetcher implementation in React Native library (the second parameter in the line, which we left it null). So if someone has this issue, check if the line is in MainApplication.java and try comment it out to see if it works

PiotrBorowski commented 1 month ago

Issue still persist in react-native 0.74.3 :/

mateoguzmana commented 1 month ago

I'm trying to reproduce this and haven't been able to. In Android and iOS, inspecting the network requests when loading the image, seems to pass fine the headers.

Here’s an example on Android and iOS showing the headers being passed as expected:

Android and iOS network image request passing the headers correctly ```tsx ``` **Android:** image **iOS:** ![image](https://github.com/user-attachments/assets/757fe709-f7ce-4938-9e98-b73d45739e6d)

Can anyone else confirm if they’re seeing the same? I’m wondering if this issue could be related to caching: when the image is already cached on disk, for instance, it won’t make a new network request, so any new headers added wouldn’t apply.

matheusbras commented 1 week ago

@mateoguzmana I'm seeing the same issue on 0.76.2. No headers are being sent at all.