Test browser:
Version of Chrome: 52.0.2743.116
It is a simple javascript that is to open an image file from local like 'C:\002.jpg'
function run(){
var URL = "file:///C:\002.jpg";
window.open(URL, null);
}
run();
Here is my sample code.
https://fiddle.jshell.net/q326vLya/3/
Please give me any suitable suggestions.
We use Chrome a lot in the classroom and it is a must to working with local files.
What we have been using is "Web Server for Chrome". You start it up, choose the folder wishing to work with and go to URL (like 127.0.0.1:port you chose)
It is a simple server and cannot use PHP but for simple work, might be your solution:
https://chrome.google.com/webstore/detail/web-server-for-chrome/ofhbbkphhbklhfoeikjpcbhemlocgigb
1)
Open your terminal and type
npm install -g http-server
2)
Go to the root folder that you want to serve you files and type:
http-server ./
3)
Read the output of the terminal, something kinda http://localhost:8080 will appear.
Everything on there will be allowed to be got.
Example:
background: url('http://localhost:8080/waw.png');
Okay folks, I completely understand the security reasons behind this error message, but sometimes, we do need a workaround... and here's mine. It uses ASP.Net (rather than JavaScript, which this question was based on) but it'll hopefully be useful to someone.
Our in-house app has a webpage where users can create a list of shortcuts to useful files spread throughout our network. When they click on one of these shortcuts, we want to open these files... but of course, Chrome's error prevents this.
This webpage uses AngularJS 1.x to list the various shortcuts.
Originally, my webpage was attempting to directly create an <a href..> element pointing at the files, but this produced the "Not allowed to load local resource" error when a user clicked on one of these links.
<div ng-repeat='sc in listOfShortcuts' id="{{sc.ShtCut_ID}}" class="cssOneShortcutRecord" >
<div class="cssShortcutIcon">
<img ng-src="{{ GetIconName(sc.ShtCut_PathFilename); }}">
</div>
<div class="cssShortcutName">
<a ng-href="{{ sc.ShtCut_PathFilename }}" ng-attr-title="{{sc.ShtCut_Tooltip}}" target="_blank" >{{ sc.ShtCut_Name }}</a>
</div>
</div>
The solution was to replace those <a href..> elements with this code, to call a function in my Angular controller...
<div ng-click="OpenAnExternalFile(sc.ShtCut_PathFilename);" >
{{ sc.ShtCut_Name }}
</div>
The function itself is very simple...
$scope.OpenAnExternalFile = function (filename) {
//
// Open an external file (i.e. a file which ISN'T in our IIS folder)
// To do this, we get an ASP.Net Handler to manually load the file,
// then return it's contents in a Response.
//
var URL = '/Handlers/DownloadExternalFile.ashx?filename=' + encodeURIComponent(filename);
window.open(URL);
}
And in my ASP.Net project, I added a Handler file called DownloadExternalFile.aspx which contained this code:
namespace MikesProject.Handlers
{
/// <summary>
/// Summary description for DownloadExternalFile
/// </summary>
public class DownloadExternalFile : IHttpHandler
{
// We can't directly open a network file using Javascript, eg
// window.open("\\SomeNetworkPath\ExcelFile\MikesExcelFile.xls");
//
// Instead, we need to get Javascript to call this groovy helper class which loads such a file, then sends it to the stream.
// window.open("/Handlers/DownloadExternalFile.ashx?filename=//SomeNetworkPath/ExcelFile/MikesExcelFile.xls");
//
public void ProcessRequest(HttpContext context)
{
string pathAndFilename = context.Request["filename"]; // eg "\\SomeNetworkPath\ExcelFile\MikesExcelFile.xls"
string filename = System.IO.Path.GetFileName(pathAndFilename); // eg "MikesExcelFile.xls"
context.Response.ClearContent();
WebClient webClient = new WebClient();
using (Stream stream = webClient.OpenRead(pathAndFilename))
{
// Process image...
byte[] data1 = new byte[stream.Length];
stream.Read(data1, 0, data1.Length);
context.Response.AddHeader("Content-Disposition", string.Format("attachment; filename={0}", filename));
context.Response.BinaryWrite(data1);
context.Response.Flush();
context.Response.SuppressContent = true;
context.ApplicationInstance.CompleteRequest();
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
And that's it.
Now, when a user clicks on one of my Shortcut links, it calls the OpenAnExternalFile function, which opens this .ashx file, passing it the path+filename of the file we want to open.
This Handler code loads the file, then passes it's contents back in the HTTP response.
And, job done, the webpage opens the external file.
Phew ! Again - there is a reason why Chrome throws this "Not allowed to load local resources" exception, so tread carefully with this... but I'm posting this code just to demonstrate that this is a fairly simple way around this limitation.
Just one last comment: the original question wanted to open the file "C:\002.jpg". You can't do this. Your website will sit on one server (with it's own C: drive) and has no direct access to your user's own C: drive. So the best you can do is use code like mine to access files somewhere on a network drive.
Chrome specifically blocks local file access this way for security reasons.
Here's an article to workaround the flag in Chrome (and open your system up to vulnerabilities):
http://www.chrome-allow-file-access-from-file.com/
There is a workaround using Web Server for Chrome. Here are the steps:
Add the Extension to chrome.
Choose the folder (C:\images) and launch the server
on your desired port.
Now easily access your local file:
function run(){
// 8887 is the port number you have launched your serve
var URL = "http://127.0.0.1:8887/002.jpg";
window.open(URL, null);
}
run();
PS: You might need to select the CORS Header option from advanced setting incase you face any cross origin access error.
This issue come when I am using PHP as server side language and the work around was to generate base64 enconding of my image before sending the result to client
$path = 'E:/pat/rwanda.png';
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);
$base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
I think may give someone idea to create his own work around
Thanks
Google Chrome does not allow to load local resources because of the security. Chrome need http url. Internet Explorer and Edge allows to load local resources, but Safari, Chrome, and Firefox doesn't allows to load local resources.
Go to file location and start the Python Server from there.
python -m SimpleHttpServer
then put that url into function:
function run(){
var URL = "http://172.271.1.20:8000/" /* http://0.0.0.0:8000/ or http://127.0.0.1:8000/; */
window.open(URL, null);
}
If you have php installed - you can use built-in server. Just open target dir with files and run
php -S localhost:8001
If you could do this, it will represent a big security problem, as you can access your filesystem, and potentially act on the data available there... Luckily it's not possible to do what you're trying to do.
If you need local resources to be accessed, you can try to start a web server on your machine, and in this case your method will work. Other workarounds are possible, such as acting on Chrome settings, but I always prefer the clean way, installing a local web server, maybe on a different port (no, it's not so difficult!).
See also:
Open local files(file://) using Chrome
Opening local files from chrome
You just need to replace all image network paths to byte strings in stored Encoded HTML string.
For this you required HtmlAgilityPack to convert Html string to Html document.
https://www.nuget.org/packages/HtmlAgilityPack
Find Below code to convert each image src network path(or local path) to byte sting.
It will definitely display all images with network path(or local path) in IE,chrome and firefox.
string encodedHtmlString = Emailmodel.DtEmailFields.Rows[0]["Body"].ToString();
// Decode the encoded string.
StringWriter myWriter = new StringWriter();
HttpUtility.HtmlDecode(encodedHtmlString, myWriter);
string DecodedHtmlString = myWriter.ToString();
//find and replace each img src with byte string
HtmlDocument document = new HtmlDocument();
document.LoadHtml(DecodedHtmlString);
document.DocumentNode.Descendants("img")
.Where(e =>
{
string src = e.GetAttributeValue("src", null) ?? "";
return !string.IsNullOrEmpty(src);//&& src.StartsWith("data:image");
})
.ToList()
.ForEach(x =>
{
string currentSrcValue = x.GetAttributeValue("src", null);
string filePath = Path.GetDirectoryName(currentSrcValue) + "\\";
string filename = Path.GetFileName(currentSrcValue);
string contenttype = "image/" + Path.GetExtension(filename).Replace(".", "");
FileStream fs = new FileStream(filePath + filename, FileMode.Open, FileAccess.Read);
BinaryReader br = new BinaryReader(fs);
Byte[] bytes = br.ReadBytes((Int32)fs.Length);
br.Close();
fs.Close();
x.SetAttributeValue("src", "data:" + contenttype + ";base64," + Convert.ToBase64String(bytes));
});
string result = document.DocumentNode.OuterHtml;
//Encode HTML string
string myEncodedString = HttpUtility.HtmlEncode(result);
Emailmodel.DtEmailFields.Rows[0]["Body"] = myEncodedString;
Chrome and other Browser restrict the access of a server to local files due to security reasons. However you can open the browser in allowed access mode. Just open the terminal and go to the folder where chrome.exe is stored and write the following command.
chrome.exe --allow-file-access-from-files
Read this for more details
This way, However, didn't work for me so I made a different route for every file in a particular directory. Therefore, going to that path meant opening that file.
function getroutes(list){
list.forEach(function(element) {
app.get("/"+ element, function(req, res) {
res.sendFile(__dirname + "/public/extracted/" + element);
});
});
}
I called this function passing the list of filename in the directory __dirname/public/extracted and it created a different route for each filename which I was able to render on server side.
This is for google-chrome-extension
const url = "file:///C:\002.jpg"
chrome.tabs.create({url, active:true})
manifest.json
{
"name": "",
"manifest_version": 3,
"permissions": [
"activeTab",
"tabs"
],
// ...
}
This solution worked for me in PHP. It opens the PDF in the browser.
// $path is the path to the pdf file
public function showPDF($path) {
if($path) {
header("Content-type: application/pdf");
header("Content-Disposition: inline; filename=filename.pdf");
#readfile($path);
}
}
I've encounterd this problem, and here is my solution for Angular, I wrapped my Angular's asset folder in encodeURIComponent() function. It worked. But still, I'd like to know more about the risk of this solution if there's any:
```const URL = ${encodeURIComponent(/assets/office/file_2.pdf)}
window.open(URL)
I used Angular 9, so this is my url when I clicked open local file:
```http://localhost:4200/%2Fassets%2Foffice%2Ffile_2.pdf```
In the case of audio files, when you give <audio src="C://somePath"/>, this throws an error saying cannot load local resource.
This makes sense because any webpage can't simply give a local path and access your private files.
In case you are trying to play audio with dynamic paths, by changing src property through JS, then here is a sample implementation using Flask server and HTML.
server.py
#app.route("/")
def home():
return render_template('audioMap.html')
#app.route('/<audio_file_name>')
def view_method(audio_file_name):
path_to_audio_file = "C:/Audios/yourFolderPath" + audio_file_name
return send_file(
path_to_audio_file,
mimetype="audio/mp3",
as_attachment=True,
attachment_filename="test.mp3")
audioMap.html
{% raw %}
<!DOCTYPE html>
<html>
<body>
AUDIO: <audio src="Std.mp3" controls >
</body>
</html>
{% endraw %}
Explanation:
When you give the audio file name under src property, this creates a get request in the flask as shown
127.0.0.1 - - [04/May/2021 21:33:12] "GET /Std.mp3 HTTP/1.1" 200 -
As you can see that, the flask has sent a Get request for the Std.mp3 file. So to serve this get request, we wrote an endpoint that takes the audio file name, reads it from the local directory, and returns it back. Hence the audio shows up on UI.
Note: This works only if you are rendering your HTML file using the
render_template method via flask or to say, using flask as your web server.
Google Chrome does not allow to load local resources because of the security .
There is a simple solution for this problem .
1.install live-server plugin in vscode
2.open the html file by live-server
The server is sending video frame. I would like to use them in order to do a streaming. I wonder how I could assemble the frames to create a streaming video. So far, I could display the frames as pictures. Below is my angular code
component angular
getVideo() {
interval(250).switchMap(() => this.appService.getPictures())
.subscribe(data => {
const file = new Blob([data], {type:'image/png'});
this.url = this.sanitizer.bypassSecurityTrustResourceUrl(URL.createObjectURL(file));
})
}
template html
<img div="test" [src]="url" width="400px" height="300px"/>
I am trying to change the picture using the frame rate of the camera. But my picture is not updated and it freezes my browser due to the high number of http requests.
What I want to achieve is to buffer the frame in order to use the video tag instead of the img tag the same way I would connect to a live streaming send by a server using the video tag with src set to the url of the server.
Github link: https://github.com/kedevked/frameProcessing
Instead of triggering http request at a certain interval of times, using websocket is better.
By displaying the images frame by frame, it gives the impression of a live video. The only thing though is that there might be latency in the network which makes the frame rate not to be constant. However, it works well for use cases where buffering the video server side could not be considered such as when we need to send data along each frame.
service using websocket
createStream(url) {
this.ws = webSocket<any>(url);
return return this.ws.asObservable()
}
component
constructor (private streamingService: StreamingService) {}
ngOnInit(): void {
this.getStream()
}
getStream() {
this.streamingService.createStream().subscribe(data => {
const file = new Blob([data], {type:'image/png'});
this.url = this.sanitizer.bypassSecurityTrustResourceUrl(URL.createObjectURL(file));
})
}
This solution is well suited when we are sending not only image but also data along the image. In this scenario, the image needs to be sent as base64.
getStream() {
this.streamingService.createStream().subscribe(data => {
this.url = data.base64ImageData
})
}
Since the base64 encoding has a payload of 133% of the initial image, it might be costly to use it in all settings. In case the image needs to be served along with other data, the whole data can be sent as a binary. This will require encoding the data server-side and decode it client-side.
Since this might require a bit of computation, using a web-worker can be considered for not only decoding the data but also for displaying the image.
If the image is sent as a binary, using canvas for rendering will be faster
canvas.getContex('2d').putImageData(imageBinaryData, 0, 0)
I see two problems here, that may improve this solution.
First of all, how do you know that the request will spend less than 250 milliseconds? if not, you know that switchMap will cancel it? Maybe exhaustMap or concatMap could fit better if you don't want to lose the current request.
The second point is that the interval(X) and the HTTP request are inside the angular zone, so they will fire change detection... This could bring you several performance issues. So you should run the interval and the request outside the zone and detect changes manually.
Said that I will purpose a solution like this:
private subscription: Subscription;
cosntructor(public ngZone: NgZone, public cd: ChangeDetectorRef){
getVideo();
}
getVideo() {
this.subscription = this.ngZone.runOutsideAngular(() =>
interval(250).pipe(exhaustMap(() => this.appService.getPictures()))
.subscribe(data => {
const file = new Blob([data], {type:'image/png'});
this.url = this.sanitizer.bypassSecurityTrustResourceUrl(URL.createObjectURL(file));
// Do change detection in orther to actualize [url] binding
this.cd.detectChanges();
})
);
}
ngOnDestroy() {
// remember to unsubscribe from interval subscription
this.subscription.unsubscribe()
}
I don't think that with this code you would have much performance issues... although this type of long polling is never good, I don't think it would freeze your app. Try it and let me know.
Hope this helps.
I have created a list of all page uris I'd like to download an image from for a vehicle service manual.
The images are delivered via a PHP script,as can be seen here http://www.atfinley.com/service/index.php?cat=g2&page=32
This is probably meant to deter behaviors like my own, however, every single Acura Legend owner shouldn't depend on a single host for their vehicle's manual.
I'd like to design a bot in JS/Java that can visit every url I've stored in this txt document https://pastebin.com/yXdMJipq
To automate the download of the available png at the resource.
I'll eventually be creating a pdf of the manual, and publishing it for open and free use.
If anyone has ideas for libraries I could use, or ways to delve into the solution, please let me know. I am most fluent in Java.
I'm thinking a solution might be to fetch the html document at each url, and download the image from the <img src>argument.
I have written something similar but unfortunately, i can't find it anymore. Nevertheless, i remember using the JSoup Java-library which comes in pretty handy.
It includes an HTTP-client and you can run CSS-selectors on the document just like with jQuery...
This is the example from their frontpage:
Document doc = Jsoup.connect("http://en.wikipedia.org/").get();
Elements newsHeadlines = doc.select("#mp-itn b a");
Creating PDFs is quite tricky, but i use Apache PDFBox for such things...
I know you asked for a JavaScript solution but I believe PHP (which you also added as a tag) is more suitable for the task. Here are some guidelines to get you started:
Move all the URLs into an array and create a foreach loop that will iterate on it.
Inside the loop use the PHP Simple HTML DOM Parser to retrieve the image URL attribute for each page.
Still inside the loop use the URL for the image in a CURL request to grab the file from that and save it into your custom folder. You can find the code required for this part here.
If this process proves to be too long and you get a PHP runtime error consider storing the URLs generated by step 2 in a file and then using that file to generate a new array and run step 3 on it as a separate process.
Finished solution for grabbing image urls;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Scanner;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
public class Acura {
public static void main(String[] args) throws IOException {
Scanner read;
Writer write;
try {
File list = new File("F:/result.txt");
read = new Scanner(list);
write = new FileWriter("F:/imgurls.txt");
double s = 0;
while(read.hasNextLine())
try {
s++;
String url = read.nextLine();
Document doc = Jsoup.connect(url).get();
Element img = doc.select("img").first();
String imgUrl = img.absUrl("src");
write.write(imgUrl + "\n");
System.out.println((double)(s/2690) + "%");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
read.close();
write.close();
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
Generates a nice long list of image urls in a text document.
Could have done it in a non-sequential manner, but was heavily intoxicated when I did this. However I did add a progress bar for my own peace of mind :)
Scanner read;
Writer write;
try {
File list = new File("F:/imgurls.txt");
read = new Scanner(list);
double s = 0;
while(read.hasNextLine())
try {
s++;
String url = read.nextLine();
Response imageResponse = Jsoup.connect(url).ignoreContentType(true).execute();
FileOutputStream writer = new FileOutputStream(new java.io.File("F:/Acura/" + (int) s + ".png"));
writer.write(imageResponse.bodyAsBytes());
writer.close();
System.out.println((double)(s/2690) + "%");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
read.close();
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
Worked for generating pngs
I have a spring boot rest service with endpoints defined like this:
#RequestMapping(value = "...", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE) //and octet for videos
#ResponseBody
public ResponseEntity<byte[]> get(...) {
//get image as byte array and return
}
And the client side in javascript (angular) :
var headers = {headers : {..., "Accept":"image/jpeg"}}
var response = $http.get(...);
obj.imageSrc = 'data:image/jpg;base64,' + response;
obj.Image = new Image();
obj.Image.src = obj.imageSrc;
What I require
I thought this endpoint would behave like a regular image file on a file server so that the client can just do a get on it (for reasons outside the scope of this question, it can't actually be a raw image to access with a URL). Apparently this isn't the case - the byte array has to be converted to base64 (is there a way around this, since the array becomes much bigger), which has the effect of rotating the image. I wrongly thought getting an image from an API like this in javascript would be easy :(
Secondly, doing it this way means that javascript has to download the entire array. Is there a way I can define the endpoint to allow for a stream so that javascript can get it in chunks (I imagine both Spring and JS have utility functions that would handle this?)
The basic underlying question
How do I implement this properly in Spring so as to be as Javascript friendly as possible? Bearing in mind I want to serve both images (~5MB) and videos (~100MB)
Thanks in advance.
EDIT
Perhaps I should be using FileResourceStream as the return type? No idea if this is the "right" way.
1) Don't use a data url. Use the direct url of your controller-method.
2) Write directly to the http-response's output:
#RequestMapping(value = "/dyna.jpg", method = RequestMethod.GET, produces = MediaType.IMAGE_JPEG_VALUE)
public void getImage(HttpServletResponse response) {
//write byte-array or -stream to the response using
// response.getOutputStream()
}
P.S. In case you really need the data url there is no otherway around as you do it, since they require the base64 encoding
Does anybody know how to read google gears blob objects within the browser? I'm using gwt on top of gears, but I'm looking for any kind of solutions. The application needs to work fully offline so I can't post the files and process them server side. My files are simple text files that I want to upload and parse in offline mode.
I wrote a very simple class to do this you can check it out here:
http://procbits.com/2009/07/29/read-file-contents-blobs-in-gwt-and-gears/
It's very simple to use. Either call the method "readAllText" or you can read it line by line. Here is an example reading line by line:
try {
Desktop dt = Factory.getInstance().createDesktop();
dt.openFiles(new OpenFilesHandler(){
public void onOpenFiles(OpenFilesEvent event) {
File[] files = event.getFiles();
File file = files[0];
Blob data = file.getBlob();
BlobReader br = new BlobReader(data);
while (!br.endOfBlob())
Window.alert(br.readLine());
}
}, true);
} catch (Exception ex){
Window.alert(ex.toString());
}
I hope this helps!
Have you looked at the Google Gears API documentation (for JavaScript)?