meteor / meteor

Meteor, the JavaScript App Platform
https://meteor.com
Other
44.07k stars 5.16k forks source link

meteor/cordova/ios not allowed to load local resource on IOS #3799

Closed dotnetwise closed 8 years ago

dotnetwise commented 9 years ago

_9 Upvotes_ We are using the file transfer plugin to download a file to file:///var/mobile/Containers/Data/Application/6BB3B78C-0BAA-42FF-93F0-C70B80B86944/tmp/cdv_photo_003.jpg

However, then trying to access that path with an <img tag will give us security errors: Not allowed to load local resource: file:///var/mobile/Containers/Data/Application/6BB3B78C-0BAA-42FF-93F0-C70B80B86944/tmp/cdv_photo_003.jpg

This won't happen in a normal cordova app since it starts via file:/// protocol

However meteor breaks this beacuse the app will start on http://meteor.local

So, how to give access to the app's file:/// sandbox files?

Slava commented 9 years ago

You are right, there is no good way to do it right now.

dotnetwise commented 9 years ago

So, why enforce http://meteor.local then?

I think there should be an option to be on the file protocol so that would be the same as normal cordova app.

What about file:///meteor.local to be "served" the same way as http://meteor.local This way would also fix the android 2.3 buggy http://meteor.local and would also keep the same functionality/behavior as for a normal cordova (meteorless) app.

What do you think?

Slava commented 9 years ago

The environment on file:// urls doesn't match the environment you get in the browser on a regular website. A lot of this has to do with cross-origin requests, single-page routing, hash fragments and problems coming out of this approach.

dotnetwise commented 9 years ago

Yes, but none of them are a problem in a normal cordova app.

And if we are migrating from an existing app towards meteor then we will have a broken app, just because the app won't run in a file:/// environment anymore.

So, at least give us the option in the mobile-config.js to specify the http://meteor.local or file:///meteor.local or anything else.

ddresch commented 9 years ago

What exactly does this mean? It's not possible to access downloaded files in any way? Are there any solutions or practices how to download and store larger assets like sounds etc. AND access these later on?

I mean this is not an rare use case, it's pretty common I guess. appcache is probably not the best solution to build on if you handle bigger files, I got no experience with it so this is more a question.

glasser commented 9 years ago

Just closed #3229 as duplicate of this. It contains a good reproduction: https://github.com/jperl/repro-meteor-3229

glasser commented 9 years ago

https://github.com/phonegap/phonegap-app-developer/issues/134 https://muut.com/i/appgyver/steroids:using-file-uri-not-showing https://github.com/AppGyver/kitchensink/blob/master/app/controllers/camera.coffee#L67 https://code.google.com/p/chromium/issues/detail?id=40787

It sounds like this isn't a Meteor problem so much as a general issue on Cordova/WebKit apps. If they're not running from file: they can't access file:, even with CORS configured. So unless I'm confused there's not much you can do. The camera.coffee there seems to show something where it moves the file to another path that it then serves via an http server and uses a /foo URI instead of file:.

nate-strauser commented 9 years ago

i came up with a workaround for this. use the cordova http server plugin (https://github.com/floatinghotpot/cordova-httpd) to serve up the downloaded files.

flow is like so: start up web server on app startup (localhost only) file transfer does download to device storage http server serves up downloaded files meteor app loads assets from urls like "http://127.0.0.1/"

i wonder if we could add an option into the cordova autoupdate server to offer this functionality. eg: a 'files' directory that would be usable for downloads and then serving to the app

Slava commented 9 years ago

@nate-strauser as a matter of fact, we already use cordova-httpd: https://github.com/meteor/com.meteor.cordova-update

nate-strauser commented 9 years ago

@Slava i saw that! that's what i was referring to as "the cordova autoupdate server"

I was thinking that we could offer a config option that would serve up a particular directory in addition to the application assets. i didn't really dig into the file structure of the cordova update functionality. would it be advisable to just download files into the same area which meteor downloads new application code?

Slava commented 9 years ago

would it be advisable to just download files into the same area which meteor downloads new application code?

@nate-strauser Not sure what you mean by this sentence.

If you want to play with the changes to meteor-update, here are two ways to do that, I will describe the one that is a bit more hassle but generally has no issues with caching of xcode, etc:

nate-strauser commented 9 years ago

maybe this will be a little more clear...

see my example app which uses a web server to serve up files written to the file system with the file transfer plugin - https://github.com/nate-strauser/meteor-offline-mobile-files-demo - works very well after files are downloaded and connection is dropped

what i was suggesting is that instead of this 2 http server solution, the autoupdate http server could provide the same capability (serve up some files from the filesystem to the app as well as provide app code updates)

http server

just wanted to see what the core team / community thought about this as a solution to the file storage problem

miri-am commented 9 years ago

to me this is not some edge case but a core functionality in most mobile apps. There needs to be an easy way to access locally saved files.

icenpop commented 9 years ago

@miri-am +1

udiedrichsen commented 8 years ago

I tried the last week to get access to local files in meteor cordova app without success. Why is this not possible ?

@miri-am +1

qdsang commented 8 years ago

@miri-am +1

harellevy commented 8 years ago

+1

artichox commented 8 years ago

This has been an issue for me as well. +1

yiluxin commented 8 years ago

+1!This problem cause I need to rework,can't to resolve

sicter commented 8 years ago

+1 rather large issue for me, really need a solution

shishircc commented 8 years ago

+1 large issue for me too. I spent 3 days trying to figure out what I was doing wrong compared to the samples on the web for cordova. I am sure lot of people are stumped by this issue.

artichox commented 8 years ago

@nate-strauser Thank you for your offline-files demo! Solved the problem beautifully for me.

nate-strauser commented 8 years ago

:) glad it helped

i'm in the process of turning the file server portion of that demo into a package for easy use - should have that out in a week or so

On Thu, Jul 16, 2015 at 1:01 PM, Lucy Richards notifications@github.com wrote:

@nate-strauser https://github.com/nate-strauser Thanks you for your offline-files demo! Solved the problem beautifully for me.

— Reply to this email directly or view it on GitHub https://github.com/meteor/meteor/issues/3799#issuecomment-122022416.

artichox commented 8 years ago

wonderful -- that will be well appreciated by the community.

martijnwalraven commented 8 years ago

@nate-strauser Thanks for your work on this issue. I won't be able to spend time on this for a few weeks, but my intention is to look into it as part of improvements to the Cordova integration that I hope to get into the Meteor 1.2 release. I'd like to move part of the Hot Code Push functionality into native code, and that might open up opportunities for dealing with other file access.

nate-strauser commented 8 years ago

@martijnwalraven are you planning to have the app code still be served up from http://meteor.local? if you change it to be served from the filesystem, then we should be able to load files from a file:// url without needing a http server to proxy them. it seems the root issue here is a http:// originated app is blocked from trying to access file:// resources. i'm not really pushing for a particular path here, just curious.

let me know if you wanted to chat further about this or i can help in any way. my plan was to roll out a couple packages related to cordova issues i've dealt with recently. mainly accessing files on the filesystem and downloading files for offline use. my demo project lays out solutions to these issues, but i'd prefer to deliver a set of easily reusable packages.

martijnwalraven commented 8 years ago

To be honest, I haven't had a chance to think about this in detail, but from what I understand the reason to serve files from http://meteor.local instead of file:// urls is that the latter don't support pushState properly. That seems like a good reason to stick with it, unless you know of another workaround.

I'd definitely be interested in learning more about the Cordova issues you've run into and the solutions you've found. I'm fairly new to Cordova myself (having done primarily native mobile development) and feel the current Cordova integration could use some improvements.

Ideally, features like this should just work and not require additional packages/plugins. Having more control over the native wrapper might help I think, but I'll need to spend more time on this to know whether that is the right direction.

henkstom commented 8 years ago

I found a way to work around this problem. I use the internalURL cdvfile://

   rootToURL = fileSystem.root.toURL();
   rootToInternalURL = fileSystem.root.toInternalURL();
   image.src = imageURL.replace(rootToURL,rootToInternalURL);

"file:///var/mobile/Containers/Data/Application/DC66B184-9051-44E2-923F-2335925514F5/Documents/tmp/uuid23620.jpg"
"cdvfile://localhost/persistent/tmp/uuid23620.jpg"

It works for me with images on iOS.

udiedrichsen commented 8 years ago

@henkstom How do you set the imageURL ? cdvfile://localhost/persistent/dcim or cdvfile://meteor.local/persistent/dcim

henkstom commented 8 years ago

i used

cdvfile://localhost/persistent

nate-strauser commented 8 years ago

i wanted this to work as the cordova http server solution feels clumsy, but it appears to only work for images - see https://github.com/nate-strauser/meteor-offline-mobile-files-demo/tree/cdv-test

images appear to download and then load from the device just fine, but video and audio do not seem to work (they download fine, but will not load from the internal url) - i'm wondering if it is related to this issue - https://issues.apache.org/jira/browse/CB-6051 - i also tried to load in the cordova file + media plugins, but that doesn't seem to help https://github.com/nate-strauser/meteor-offline-mobile-files-demo/blob/cdv-test/.meteor/cordova-plugins

unfortunately, i don't believe the cdvfile:// urls work for complex media like audio and video :(

dekel1207 commented 8 years ago

I have the same error message when trying to access contact images. Setting an img src to something like "content://com.android.contacts/contacts/30470/photo" works with plain cordova but not with meteor project. Is there a workaround for this? It is a rather common requirement from a mobile application...

IstoraMandiri commented 8 years ago

Thanks @henkstom for the workaround. I'm at least able to display an image in the DOM now.

Problem is, now I'm now getting [Error] Unable to get image data from canvas because the canvas has been tainted by cross-origin data. (when using canvas) even though I have App.accessRule("*") in mobile-config.js.

Any ideas?

henkstom commented 8 years ago

I have the same problem. I'm trying with cordova-httpd. And searching for a way to set the CORS header.

sday commented 8 years ago

"There needs to be an easy way to access locally saved files."

agreed

IstoraMandiri commented 8 years ago

I was able to get around my video streaming from camera issue by sending base64 data from the native app but the test iPad got warm pretty quick. Looks like it would need throttling.

dwilt commented 8 years ago

:+1: on this needing to be easier

johanbuys commented 8 years ago

+1 Major stumbling block at the moment.

martijnwalraven commented 8 years ago

I've heard you! This is definitely at the top of my todo list for after the Meteor 1.2 release, together with Hot Code Push improvements.

johanbuys commented 8 years ago

@martijnwalraven Thanks a mill for all the hard work! :)

derwaldgeist commented 8 years ago

@martijnwalraven: Thanks for taking care of this. I've just run into the same issue. Having a storage for any kind of rich media is an absolute must for most mobile apps, IMHO. My app is depending heavily on photos/videos taken by the user, and now I'm kinda stuck. :-/

derwaldgeist commented 8 years ago

@nate-strauser: Any update on your planned public packages so far? Would love to hear they're finished, as this is a major road block for me, like for the others here.

nate-strauser commented 8 years ago

@derwaldgeist here you go! https://atmospherejs.com/natestrauser/cordova-file-server

This package just provides the http server part for you. You still need to deal with downloading files and sending the correct url (local or remote) to the template. In the future, I may make this functionality a separate package that depends on the cordova-file-server package.

vigile commented 8 years ago

Wonderful !!! Thank you Le 3 sept. 2015 23:30, "Nathan Strauser" notifications@github.com a écrit :

@derwaldgeist https://github.com/derwaldgeist here you go! https://atmospherejs.com/natestrauser/cordova-file-server

This package just provides the http server part for you. You still need to deal with downloading files and sending the correct url (local or remote) to the template. In the future, I may make this functionality a separate package that depends on the cordova-file-server package.

— Reply to this email directly or view it on GitHub https://github.com/meteor/meteor/issues/3799#issuecomment-137549420.

derwaldgeist commented 8 years ago

Thanks, this in great news!

adrianolsk commented 8 years ago

I got the same error when trying to display a contact picture on android

Not allowed to load local resource: content://com.android.contacts/contacts/10

@nate-strauser do you think your package would work in this case?

ilampirai commented 8 years ago

When I try the package natestrauser/cordova-file-server

Got the following error : starting server at /storage/emulated/0/ failed to start server: IO Exception: Host is unresolved: 127.0.0.1

plz help @nate-strauser

byrne-yan commented 8 years ago

@ilampirai @nate-strauser I met the same issue. When I forked the project and then changed the 'localhost_only' to false, it worked.

ilampirai commented 8 years ago

Thanks @byrne-yan your fix works well.

@nate-strauser Is there a way to send www_root , port and localhost flag from our meteor js file ? (in meteor.startup function) that will be helpful greatly can you make your package work so?

nate-strauser commented 8 years ago

i updated the package default for localhost_only to be false. I also added the ability to override all the http server options via meteor settings. hopefully this works for you all!

@adrianolsk it might. you seem to be experiencing the same issue with not being able to load content across protocols. although i'm not sure how you would be able to access contact pictures via the filesystem access that my package provides.