1

I'm trying to display images hosted in the public directory of my rails app on a different website. I basically don't want a user to be able to type the src of the image tag into a browser and access the uri for my app where the image can be found.

After doing some digging, I determined that the way to achieve this may be to send the image as base64 encoded data, and then rebuild the image from that data on the website receiving the ajax response. Please let me know if I am mistaken.

I've successfully sent the base64 data from my rails app to my website through ajax, but I'm having difficulty building an image from the data.

This is my rails code:

def send_image(blank=nil)
  require 'base64'
  @image= "#{Rails.root}/public/test.jpg"
  @imageEncoded = Base64.encode64(@image)

send_data @imageEncoded, :type => 'text/plain', disposition: "inline", :x_sendfile=> true

end 

This is the ajax response:

    L2FwcC9wdWJsaWMvcHVwcHkuanBn

This is the code to build the image from the ajax response:

    $("#picture").attr("src","data:image/jpg;base64," + data);

I think I may be misunderstanding how this all works. When I get back the endcoded data and insert it into the src, an image is not displayed. It just shows a broken image icon.

If I send just the image file by itself (without encoding the data), the picture shows up in the ajax response when I look in the Network tab of the developer tools, but I cannot use that data to build an image. The data response looks like this:

    ���� :ExifMM*  � s � � � ( 1 � 2 ҇i � -��' -��' Adobe Photoshop CS5 Macintosh2015:05:20 15:25:20 � 0221� ��� �� � n v ( ~ �H H ����Adobe_CM �� Adobed� ���        �� x� " �� �� ? 3 ! 1 AQa "q�2 ���B#$ R�b34r��C %�S���cs5 ���&D�TdE£t6 �U�e���u��F'���������������Vfv��������7GWgw�������� 5 !1 AQaq" 2�� ��B#�R��3$b�r��CS cs4�% ��� &5��D�T� dEU6te����u��F���������������Vfv��������'7GWgw������� ?�T�I%)$�IJI$�R�I$���I%)$�IJI$�R�I$���I%)$�IO���T�I%)$�IJI #&� .�dž�J��ɶ��0?ю Ys� o.̘�J~ �z�Ugk �Ø� iU~u�: ��* >� � hL�^� HЎ$*Y9��;��ѵ ��_7I���� �� [� � � � � HI ��K�D�� c ӈ�uQ� � a��;C���;\�} s V%e��)��lm���K r_�-�\��i�IT�/�sa�A�Q�z��1*�r�@ wk�H ��!�� ~��� �O�DN ���7 I$�B�I$�����T�I%) /)��op�th�(� ���2KX k=�?�Qg�����@Ɇ s��԰ �� k��* u�%���\�W��Oc��� ϱ�Ǭ�y��=�� i?�z1�� A�+�<��Vvo� Q��Z� / �c� �����Of�+�5�hy2����; � ���:Ů=c���W]m kˁ��m{v��Ќx�t�e d[���7# ��6ڈp�S � � �Nr�!� N��X8�{�w=�p ��#��+��u�>Ө�S���� ��n����i� � �� B�C�5�'� y ��t�t��� kH �.�^�'� ���/ � ������X���-��-�i>+3�P�.nѸ q� � ��T*$�uu��{���;Lhc�7} ��ަ����X���㸏 �n�_K�ߣi�q �

Can someone let me know where I might be going wrong here? Do I have to send the image, and then base64 encode it and add it to the src of the image tag? Am I failing to understand how encoding works?


RESPONSE TO COMMENTS

So the code that I would have to write looks like this?

var request = new XMLHttpRequest();
request.responseType = "blob";
request.open("GET", railsAppEndpoint);

*This is where I'm unclear as to how to proceed based on your comment. I've never used fetch before. I looked up some documentation on fetch and it looks as though the first argument that you are supposed to pass into fetch is a url. Are you saying that I have to open up an XMLHttpRequest, and then also use fetch? Or is fetch supposed to replace the XMLHttpRequest.

I'm just guessing at the correct syntax here:

fetch()
 .then(
     response => response.blob()
  )

*Something seems missing here.

**At this point I don't get how to obtain the Blob url. I know how to set the src of an image, but I need to complete the other steps first.

  • _"the picture shows up in the ajax response when I look in the Network tab of the developer tools, but I cannot use that data to build an image."_ The image is already built, no? Is the response a valid `JPEG`? Can you create a jsfiddle https://jsfiddle or plnkr https://plnkr.co which contains the full `base64` response? – guest271314 Jun 07 '17 at 21:26
  • That's what happens when I send the image without encoding it. The response in the Network tab shows the picture, file name, dimensions, and the MIME Type: image/jpg. And if I right click the GET response and choose 'Open in New Tab,' I can visit the URI (which I don't want). If I encode the data and then send it, the response I get back is text/plain (the one I put in my post). If the image is already built (with the first method: sending the image w/o encoding), how do I display it? If I just insert the data response into a div, it displays the wall of weird symbols that I put in my post. – OneCaseTwoCase Jun 07 '17 at 22:09
  • Not following what issue is? Why do you not simply respond with the image file? Are you using `jQuery.ajax()` to request image? `jQuery.ajax()` does not support binary data transport by default. See https://stackoverflow.com/questions/38192854/recieving-a-zip-file-as-response-on-ajax-request/38193036#38193036, https://stackoverflow.com/questions/42106584/displaying-pdf-from-arraybuffer/42195304?s=2|2.8176#42195304 – guest271314 Jun 07 '17 at 22:11
  • Part of my question was trying to find out if what I'm attempting is possible. I don't want users to be able to download my images. In theory, I'm trying to convert my image into data on my rails app, send the data to my website, and rebuild the image from the data so that there is no uri that can be visited to view the image. But regarding your question, I don't know how to respond with the image file. As I said in before, if I send an image from rails and then write something like: document.getElementById("container").innerHTML = data; the container will have a wall of weird symbols. – OneCaseTwoCase Jun 07 '17 at 22:31
  • Why do you set `data` at `.innerHTML` of an element if you are trying to display the image? The image does not have to be downloaded. The `javascript` at linked Questions/Answers demonstrates the process of getting data from server as a `Blob` or `ArrayBuffer`, then creating a `Blob URL` or `data URI` from the response. – guest271314 Jun 07 '17 at 22:33
  • So you're saying that I have to use Blob or ArrayBuffer to be able to rebuild the image from the data I receive from an ajax response? What kind of data am I supposed to be using with Blob? The data that I get when sending the image (a.k.a the wall of weird symbols) or the base64 encoded data (which equals: L2FwcC9wdWJsaWMvcHVwcHkuanBn)? – OneCaseTwoCase Jun 07 '17 at 22:51
  • _"The response in the Network tab shows the picture, file name, dimensions, and the MIME Type: image/jpg. And if I right click the GET response and choose 'Open in New Tab,' I can visit the URI (which I don't want)."_ Not sure what you mean here? Are you trying to prevent a user from viewing the image in a separate tab? Send the image to client. At client code request the response as a `Blob`, where at `XMLHttpRequest()` `reques.responseType = "blob"`; using `fetch()` `.then(response => response.blob())`, then display the image as a `Blob URL` set at `src` of `` element. – guest271314 Jun 07 '17 at 22:56
  • Yes, ideally I'd like to prevent opening images in a different tab. I know that it's impossible to prevent an image on the internet from being downloaded (since if you are viewing an image it means it has been downloaded to your computer), but I'd like to make it as difficult as possible. I've seen a website where if you try to open the image from a GET response in another tab, the site redirects back to the main page. I thought that had to do with base64 encryption, but it may just be a controller action. I don't quite follow your code. I've updated my main post with questions about it. – OneCaseTwoCase Jun 07 '17 at 23:57
  • Then you are asking more than one Question. Not certain about the implementation that you are trying to achieve as to _"make it as difficult as possible. I've seen a website where if you try to open the image from a GET response in another tab"_. Perhaps ask the author of the site? As to requesting image as `Blob` or `ArrayBuffer` see See also https://stackoverflow.com/q/41388434/ As to updated Question, https://stackoverflow.com/questions/37510801/convert-octet-stream-to-image/, https://stackoverflow.com/questions/41085017/list-file-sizes-of-all-images-on-a-page-chrome-extension/ – guest271314 Jun 08 '17 at 00:05
  • 1
    I got the image to display using `Blob` by looking at the checked answer in the second link that you provided. Thanks a lot for all of your help! – OneCaseTwoCase Jun 08 '17 at 02:49

0 Answers0