I am trying to pull out the data with src=""; and load it into variable but with no success.
Here is the code i have been working with:
var JSONObject = document.getElementById("data").innerHTML;
console.log(JSONObject);
<script type='text/javascript' src='https://www.instagram.com/xsolvesoftware/media/' id="data"></script>
innerHTML means exactly what it says: the inner HTML. It is the HTML between <script> and </script> of which there isn't any.
If you want to read the JS then you need to getAttribute('src') and then make an HTTP request for it (e.g. with fetch or XMLHttpRequest).
The Same Origin Policy will probably block this.
Related
I have a small html/javascript webpage that I want to run in a browser offline.
In the same way the page can include an image or a css file and use it while offline, I want to include a 3mb spreadsheet that the javascript reads into a 2d-array, and I'm hoping for something that would work on IE8 as well as modern browsers.
C:\Folder\index.html
C:\Folder\code.js
C:\Folder\picture.png
C:\Folder\spreadsheet.csv
I've found multiple methods online like
<script src="jquery-csv.js"></script>
var table = $.csv.toArrays("spreadsheet.csv");
or
d3.text('spreadsheet.csv', function(error, _data){
var table = d3.csv.parseRows(_data);
});
or
$(document).ready(function() {
$.ajax({
type: "GET",
url: "data.txt",
dataType: "text",
success: function(data) {processData(data);}
});
});
But I tend to get same-origin policy errors such as:
XMLHttpRequest cannot load file://data.txt. Received an invalid response. Origin 'null' is therefore not allowed access.
Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "null" from accessing a frame with origin "null". Protocols, domains, and ports must match.
I can't seem to get these to work offline. How could I accomplish this?
Edit:
I'm managed to get the following to work for a text file only on Firefox using the CSVToArray function found here, which is pretty sluggish with a file of this size, and a hidden iframe.
Ultimately, it would be preferable if this was capable of running on IE8, and if I used a csv rather than a txt file, but at least it's a start.
<iframe style="display:none;" id='text' src = 'file.txt' onload='read_text_file()'>
</iframe>
<script type="text/javascript" >
function read_text_file() {
var text = document.getElementById('text').contentDocument.body.firstChild.innerHTML;
var table = CSVToArray(text);
}
For IE8 I managed to get this to work on a small scale but with the 3mb file it will occasionally crash the browser and will always accost the user with both a ton of warning messages that activex is being used and a wave of warnings that the script will slow down the computer.
window.onLoad = readFileInIE("file.csv");
function readFileInIE(filePath) {
try {
var fso = new ActiveXObject("Scripting.FileSystemObject");
var file = fso.OpenTextFile(filePath, true);
var text = file.ReadAll();
var table = CSVToArray(text);
file.Close();
return fileContent;
} catch (e) {
if (e.number == -2146827859) {
alert('Unable to access local files due to browser security settings. ' +
'To overcome this, go to Tools->Internet Options->Security->Custom Level. ' +
'Find the setting for "Initialize and script ActiveX controls not marked as safe" and change it to "Enable" or "Prompt"');
}
}
}
This might not work in IE8, but the HTML5 API is really useful for this. Just use:
window.onload = function() {
var fileInput = document.getElementById('fileInput');
fileInput.addEventListener('change', function(e) {
var file = fileInput.files[0];
var textType = //format you'd like to recieve;
if (file.type.match(textType)) {
var reader = new FileReader();
reader.onload = function(e) {
// apply magic here
}
reader.readAsText(file);
}
else
{
fileDisplayArea.innerText ="Sorry matey, can't help you with that filetype."
}
});
}
Then after that, a simple .html file that looks like this would do the trick:
<html lang="en">
<head>
<script src="script.js"></script>
</head>
<body>
<div id="page-wrapper">
<div>
<input type="file" id="fileInput">
</div>
<pre id="fileDisplayArea"></pre> //display any output here
</div>
</body>
</html>
It's not quite clear what you want to do.
Using jQuery it's possible to modify events that happen in the DOM. Using this you could potentially save the source code when you're done making changes. You would then need to replace your current source code with the saved code to use the changes the next time you open up the page. However, this would be a very laborious process and there are likely a number of better ways to accomplish what you want to do depending on what that is.
Also, in regards to Shota's post. You can't use AJAX unless you have a server running in the background. If you decide to set the system up on a server there are a number of options for accomplishing what you want.
My comment become too long.
You can't include data files in the same way as media. The easiest way would be to preprocess the csv into a js array and then include the csv like js <script src="mydata.csv.js"></script>.
By offline you mean local files and not public? The first suggestion would be to upgrade your browser. It doesn't quiet make sense if its a local file supporting all major browsers. Sorry I'm sure you have reasons why you can't. But upgrading would get around the non Ecmascript 5 support in ie8.
To get around the cross origin policy you'd have to run your file on a local webserver. So your html page would be on something like localhost:8080 and your csv localhost:8080/mydata.csv this gives privileges to the html to allow access to the csv file as they're now on the same domain. D3, jquerycsv should now work. Its a big security risk allowing any html file to access the filesystem freely.
If a local server isn't an option. You have to select the file each time you load with an input field. This grants the browser permissions to access this file.
After selecting the file, to read the contents for the main browsers (with Ecma5) look into FileReader on MDN, and an example of use can be found here. For ie8 + 9 there is VBscript support to read files. You can use VB just like JS using <script type="text/vbscript"></script>
If you really want to access local resources from a sever page then you need also a local page that allows the access. A local HTML page inside an <iframe> could read the text file and post contents to the main page via window.postMessage().
There might also be a way with HTML5 iframes and the sandbox attribute, but not in IE9 and below.
see:
https://developer.mozilla.org/en-US/docs/Web/API/Window.postMessage
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe
As you have realized, any AJAX-based solution will be affected by security restrictions for local file access. Instead of finding browser-specific workarounds, you could go the JSONP way which avoids AJAX.
This would require you to pre-process your CSV data and save it in a more JS-friendly format. But this would be a good idea anyway, as native JS parsing is likely to perform better than a CSV parser implemented in JS.
It could look roughly like this:
index.html
</head>
<body>
<div id="page-wrapper">
<div>
<input type="file" id="fileInput">
</div>
<pre id="fileDisplayArea"></pre> <!-- display any output here -->
</div>
<script src="script.js"></script>
<script src="data.js"></script>
</body>
</html>
script.js
function processData(data) {
// Your logic
// (will be called once data.js is loaded)
}
data.js
processData([
["your", "data"]
]);
I'm trying to download some data using pure javascript/html from cross-domain, dropbox to be specific.
<html>
<head>
</head>
<body>
<div id = 'twitterFeed'></div>
<script>
function myCallback(dataWeGotViaJsonp){
var text = '';
var len = dataWeGotViaJsonp.length;
for(var i=0;i<len;i++){
twitterEntry = dataWeGotViaJsonp[i];
text += '<p><img src = "' + twitterEntry.user.profile_image_url_https +'"/>' + twitterEntry['text'] + '</p>'
}
document.getElementById('twitterFeed').innerHTML = text;
}
</script>
<script type="text/javascript" src="http://dl.dropbox.com/u/6438697/padraicb.json?count=10&callback=myCallback"></script>
</body>
for some reason, the json is not loading. however the json loads correctly when I make the url "http://twitter.com/status/user_timeline/padraicb.json?count=10&callback=myCallback" instead. I got this example from here
Can anybody explain why dropbox doesn't work?
thanks!
UPDATE:
<script type=text/javascript>
function myCallback(dataWeGotViaJsonp){
alert(dataWeGotViaJsonp);
}
</script>
<script type="text/javascript" src="http://dl.dropbox.com/u/6438697/test2?&callback=myCallback"></script>
returns either [object object] or undefined... something is still wrong? the contents of test.json is myCallback( {"your":"json"} );
You can't just add the word 'callback' to your URL and expect Dropbox to wrap it for JSONP. You put a JSON file on your Dropbox and shared it publicly, but Dropbox isn't a dynamic server. You need a scriptable environment to take the callback parameter value and wrap it around the JSON in order to make it "JSONP".
The reason the Twitter URL works is that their API is configured to take the callback parameter as a sign that the client is expecting JSONP, which is really just a fancy term for "a JavaScript object literal wrapped in a callback function". You tell twitter what that function will be called, and they'll return a file that the browser will execute as a script, passing the object as a parameter to your callback function.
If you don't need the JSONP callback function name to be dynamic AND you need to use Dropbox, just wrap the JSON yourself. All you need to do is edit the file, and prepend valid JSON with the name of the function, and append it with the close paren.
ie,
myCallback( {"your":"json"} );
It is possible to use Google Apps Script as a proxy for hosting sites that do not support jsonp. There is writeup on how to do it here http://ramblings.mcpher.com/Home/excelquirks/jsonp
I am writing a third party javascript (my.js) that can be inserted in a HTML page using script tag. I want to achieve the following:
my.js gets loaded (which has a function myFunc(params))
myFunc() gets called with appropriate params (parameters can change)
putting my.js script in head is not an option
What is the best approach that I can use?
The problem is that you can't really pass parameters w/ just 1 script tag pointing to an external file, so you would have to get them from some element in the DOM:
The html:
<html>
<body>
<script src="my.js"></script>
<input id="params" type="hidden" value="'param1', 'param2', 'param3'" />
<div id="result"></div>
</body>
</html>
The javascript:
function myfunc() {
var doc = document,
params = doc.getElementById("params").value.split(","); // make an array of params
doc.getElementById("result").innerHTML = params.toString();
}
window.onload = myfunc;
Honestly though, this is a kludge. As mentioned before by Felix, you should probably just use 2 script tags -- One to get the external js file and one to call the function with the parameters you need.
You can pass parameters in via the query string and parse them out dynamically.
For example, your script tag becomes:
<script src="my.js?foo=bar"></script>
You can then get the value of the URL using:
var scripts = document.getElementsByTagName('script');
var url = scripts[ scripts.length - 1 ].getAttribute('src');
Because of the order JS is loaded by the browser, the last script on the page (while your script is executing during load) should always be your script.
Then you parse the query string. There are a bunch of questions on Stack Overflow dealing with that. Ex:
Parse query string in JavaScript
In an app that i'am creating i have to receive from the server an xml string with this format eg: <reply>
<script>
alert('Hello World!');
</script>
</reply>
when i did this using ajax work perferct, but when i try to receive the data in an iframe i can't extract the data from the frame because is not there, IE and FF open new tabs and append the data on that tab, how i avoid that and makes them insert the data on the frame.
I can do this work still using Javascript, get the result of the ajax and write it inside the iframe:
first create your iframe tag like this:
than the javascript code to insert the ajax:
var t = document.getElementById('iftarget');
h = t.contentWindow.document.getElementsByTagName('html');
h[0].innerHTML = '<h1>Hello</h1> This must work! Put your data here';
I have created a jsFiddle for this
http://jsfiddle.net/nunomazer/JGyEr/
Best Regards
Here's an interesting JS q... suppose you have:
host1.html on host1.com which references an external javascript (host2.js) on host2.com. In the host2.js, I'd like to get the location.hostname of the host serving the host2.js, but because host2.js is called inside of host1.html, it returns the location.hostname of host1.
Is there a way to get the location object of the external script within the external script being called?
I think similar questions have been asked before, and the answer was always no, this can't be done.
Workarounds:
Work through the parent document's script elements and, using a counter variable, find out which one we're in (ugh)
Output the current URL into the included script on server side, e.g. in PHP: script_current_url = <?php echo "http://".$_SERVER["HTTP_HOST"]."/".$_SERVER["REQUEST_URI"] (there's a variable for the protocol part too, I just forgot the name)
Set a variable before each <script> tag:
<script type="text/javascript">
script_current_url = "http://www.example.com/include.js";
</script>
<script type="text/javascript" src="http://www.example.com/include.js">
</script>
this is kludgy, but could be simplified by building a JS function that includes the file and sets the right variable automatically.
I like the server-side approach the best, but depending on your platform, it has other implications like having to send all .js resources through a resource-expensive interpreter.