I'm using the IP Geolocation API from Abstract
$.getJSON("https://ipgeolocation.abstractapi.com/v1/?api_key=YOUR_UNIQUE_API_KEY", function(data) {
console.log(data.ip_address);
console.log(data.country);
})
EDIT: Basically I want to create a textfile that will save all the visitor IP addresses only onto my computer since I have the source files.
How can I save data.ip_address and data.country of each user onto only my local computer and not have the user click and download anything? Save the JSON into a texfile? That JSON request is on the one and only HTML file for my Github page. I just need the simplest solution for this quick, static project. I've tried using require(fs) but I keep getting an error and read that I can't really use nodeJS for what I'm doing.
Javascript doesn't have access to the local filesystem. You need a webserver and a server side language to be able to save something to the server's filesystem.
The only solution I can think of would be to force the browser to create a file and present it as a download. Something like:
var text = data.ip_address;
text += '\n';
text += data.country;
var filename = 'myData.txt';
var blob = new Blob([text], {type: 'text/csv'});
if(window.navigator.msSaveOrOpenBlob) {
window.navigator.msSaveBlob(blob, filename);
} else {
var elem = window.document.createElement('a');
elem.href = window.URL.createObjectURL(blob);
elem.download = filename;
document.body.appendChild(elem);
elem.click();
document.body.removeChild(elem);
}
This is a nasty hack but you can run this (either on your site or in your console):
const win = window.open("", "Title", "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=780,height=200,top="+(screen.height-400)+",left="+(screen.width-840));
win.document.body.innerHTML = JSON.stringify(data);
// So in your case
$.getJSON("https://ipgeolocation.abstractapi.com/v1/?api_key=YOUR_UNIQUE_API_KEY", function(data) {
const win = window.open("", "Title", "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width=780,height=200,top="+(screen.height-400)+",left="+(screen.width-840));
win.document.body.innerHTML = JSON.stringify(data);
})
and then save that opened window to your local machine as a json file.
GitHub Pages does not support server-side languages such as PHP, Ruby, or Python.
-- from docs, so it's not possible to write files. GitHub pages serve static content, without any backend.
And even if it would be, collecting your users' location and IP into a GitHub repo might not be the best idea ever from privacy point of view.
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
I have a problem (or may be two) with saving files using HTML5 File API.
A files comes from the server as a byte array and I need to save it. I tried several ways described on SO:
creating blob and opening it in a new tab
creating a hidden anchor tag with "data:" in href attribute
using FileSaver.js
All approaches allow to save the file but with breaking it by changing the encoding to UTF-8, while the file (in current test case) is in ANSI. And it seems that I have to problems: at the server side and at the client side.
Server side:
Server side is ASP.NET Web API 2 app, which controller sends the file using HttpResponseMessage with StreamContent. The ContentType is correct and corresponds with actual file type.
But as can be seen on the screenshot below server's answer (data.length) is less then actual file size calculated at upload (file.size). Also here could be seen that HTML5 File object has yet another size (f.size).
If I add CharSet with value "ANSI" to server's response message's ContentType property, file data will be the same as it was uploaded, but on saving result file still has wrong size and become broken:
Client side:
I tried to set charset using the JS File options, but it didn't help. As could be found here and here Eli Grey, the author of FileUplaod.js says that
The encoding/charset in the type is just metadata for the browser, not an encoding directive.
which means, if I understood it right, that it is impossible to change the encoding of the file.
Issue result: at the end I can successfully download broken files which are unable to open.
So I have two questions:
How can I save file "as is" using File API. At present time I cannot use simple way with direct link and 'download' attribute because of serverside check for access_token in request header. May be this is the "bottle neck" of the problem?
How can I avoid setting CharSet at server side and also send byte array "as is"? While this problem could be hacked in some way I guess it's more critical. For example, while "ANSI" charset solves the problem with the current file, WinMerge shows that it's encoding is Cyrillic 'Windows-1251' and also can any other.
P.S. the issue is related to all file types (extensions) except *.txt.
Update
Server side code:
public HttpResponseMessage DownloadAttachment(Guid fileId)
{
var stream = GetFileStream(fileId);
var message = new HttpResponseMessage(HttpStatusCode.OK);
message.Content = new StreamContent(stream);
message.Content.Headers.ContentLength = file.Size;
message.Content.Headers.ContentType = new MediaTypeHeaderValue(file.ContentType)
{
// without this charset files sent with bigger size
// than they are as shown on image 1
CharSet = "ANSI"
};
message.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = file.FileName + file.Extension,
Size = file.Size
};
return message;
}
Client side code (TypeScript):
/*
* Handler for click event on download <a> tag
*/
private downloadFile(file: Models.File) {
var self = this;
this.$service.downloadAttachment(this.entityId, file.fileId).then(
// on success
function (data, status, headers, config) {
var fileName = file.fileName + file.extension;
var clientFile = new File([data], fileName);
// here's the issue ---^
saveAs(clientFile, fileName);
},
// on fail
function (error) {
self.alertError(error);
});
}
My code is almost the same as in answers on related questions on SO: instead of setting direct link in 'a' tag, I handle click on it and download file content via XHR (in my case using Angularjs $http service). Getting the file content I create a Blob object (in my case I use File class that derives from Blob) and then try to save it using FileSaver.js. I also tried approach with encoded URL to Blob in href attribute, but it only opens a new tab with a file broken the same way. I found that the problem is in Blob class - calling it's constructor with 'normal' file data I get an instance with 'wrong' size as could be seen on first two screenshots. So, as I understand, my problem not in the way I try to save my file, but in the way I create it - File API
I am creating a web portal where end user will upload a csv file and I will do some manipulation on that file on the server side (python). There is some latency and lag on the server side so I dont want to send the message from server to client regarding the bad format of uploaded file. Is there any way to do heavy lifting on client side may be using js or jquery to check if the uploaded file is "comma" separated or not etc etc?
I know we can do "accept=.csv" in the html so that file extension has csv format but how to do with contents to be sure.
Accessing local files from Javascript is only possible by using the File API (https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications) - by using this you might be able to check the content whether it matches your expectations or not.
Here's some bits of code I used to display a preview image clientside when a file is selected. You should be able to use this as a starting point to do something else with the file data. Determining whether its csv is up to you.
Obvious caveat:
You still have to check server side. Anyone can modify your clientside javascript to pretend a bad file is good.
Another caveat:
I'm pretty sure that you can have escaped comma characters in a valid csv file. I think the escape character might be different across some implementations too...
// Fired when the user chooses a file in the OS dialog box
// They will have clicked <input id="fileId" type="file">
document.getElementById('fileId').onchange = function (evt) {
if(!evt.target.files || evt.target.files.length === 0){
console.log('No files selected');
return;
}
var uploadTitle = evt2.target.files[0].name;
var uploadSize = evt2.target.files[0].size;
var uploadType = evt2.target.files[0].type;
// To manipulate the file you set a callback for the whole contents:
var FR = new FileReader();
// I've only used this readAsDataURL which will encode the file like data:image/gif;base64,R0lGODl...
// I'm sure there's a similar call for plaintext
FR.readAsDataURL($('#file')[0].files[0]);
FR.onload = function(evt2){
var evtData = {
filesEvent: evt,
}
var uploadData = evt2.result
console.log(uploadTitle, uploadSize, uploadType, uploadData);
}
}
I have a local text file which is kept changing by other programs. I want to write a html and javascript based web page to show the content of file dynamically. I have searched in google and found that most solutions require to get this text file via html element. I wonder if there is a way to get the file via a fixed path(lets say it is a string of the file directory) in javascript. I am using Javascript fileReader. Any help will be appreciated.
This is not possible using javascript running inside the browser. You will not be able to do anything outside the browser.
EDIT:
You could run a Node.js server though that runs on localhost and does your file operations you desire. You could build a API so your html page that you load in the browser calls your serverscript to do your file operations.
Do you understand what I mean?
How much information does the text file hold, Depending on your scenario it might be worth looking into javascript localstorage W3SCHOOLS local storage. Would that help your situation ?
What you can do is allow the user to choose the file of interest, using a file-input. Once done, the browser wil have access to the file, even though the JS wont have access to the file's full-path.
Once the user has chosen the file, you can reload it and refresh the view pretty-much as often as you please.
Here's a short demo, using a file input (<input type='file'/>) and an iframe. You can pick pretty much anything the browser will normally display, though there are limits on the size of the file that will work - due to the limit of the length of a URL - the file's data is turned into a data-url and that url is set as the source of the iframe.
As a demo, pick a file and then load it. Now, open the file in another program and change it. Finally, press the load button once again - the new content now fills the iframe. You can trigger the loading of the file by a timer or any other event in the page. As far as I'm aware, you cannot re-load it when it changes, since there's no notification from the OS - you have to use a button, timer, element event or whatever. Basically, you have to poll for changes.
<!DOCTYPE html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e);}
window.addEventListener('load', onDocLoaded, false);
function onDocLoaded()
{
// uncomment this line for on-demand loading.
byId('loadBtn').addEventListener('click', onLoadBtnClick, false);
}
// fileVar is an object as returned by <input type='file'>
// tgtElem is an <iframe> or <img> element - can be on/off screen (doesn't need to be added to the DOM)
function loadFromFile(fileVar, tgtElem)
{
var fileReader = new FileReader();
fileReader.onload = onFileLoaded;
fileReader.readAsBinaryString(fileVar);
function onFileLoaded(fileLoadedEvent)
{
var result,data;
data = fileLoadedEvent.target.result;
result = "data:";
result += fileVar.type;
result += ";base64,";
result += btoa(data);
tgtElem.src = result;
}
}
function onLoadBtnClick(evt)
{
var fileInput = byId('mFileInput');
if (fileInput.files.length != 0)
{
var tgtElem = byId('tgt');
var curFile = fileInput.files[0];
loadFromFile(curFile, tgtElem);
}
}
</script>
<style>
</style>
</head>
<body>
<button id='loadBtn'>Load</button><input id='mFileInput' type='file'/><br>
<iframe id='tgt'></iframe>
</body>
</html>
you can use nodejs to watch for a filechange using watchfile module, if you just want to watch the filechange and its content. you can run following code using node, but it only consoles the file changed in your terminal.
var fs=require('fs');
fs.watchFile('message.text', function (curr, prev) { //listens to file change
fs.readFile('message.text', function(err,data){ //reads the file
console.log(data.toString()); //consoles the file content
});
});