JavaScript - cross origin request blocked - non-server solution - javascript

I'm a desktop developer that is trying to learn some web basics on the side. I've previously put together an asp.net mvc website that worked more or less okay and am currently working on a simpler, html/css/js only website.
A number of the pages on the website will contain images, with a number of pieces of data accompanying them, so I thought I'd put together a JSON with all of the data, including the links to the images and generate the image list on page load. The problem that I ran into is the JavaScript cross origin request when trying to fetch the JSON file.
I've looked around at solutions and most of them recommend spinning up a server - either asp.net or node.js to fetch the JSON from. Couple of questions:
If I can write HTML that references image files, why can I not fetch a json from javascript? Is there a fundamental piece of understanding that I'm missing here?
Is there any other way of using a JSON without spinning up a web server? Should I try embedding it into the HTML? Is that a bad idea?
Any other pointers/links to resources with relevant info :)
// My JavaScript:
<script>
$(document).ready(function(){
buildGallery('test.json', '#gallery');
});
// Builds a collection of thumbnails from the json specified inside of specified div
function buildGallery(jsonUrl, galleryDiv){
$.getJSON(jsonUrl, function(data){
// Ensure the data is in correct format
if (typeof(data) !== 'object'){
return;
}
// Build the gallery
$.each(data['images'], function(key, image){
var thumbnail = '<img src="' + image['url'] + '"/>'
$(galleryDiv).append(thumbnail);
});
});
}
</script>
This is based of: https://api.jquery.com/jQuery.getJSON/
Thanks heaps!

There are a couple issues with what you are trying to accomplish with the provided code.
First, you are trying to make an Ajax request to a resource that is not hosted on an http server. Ajax is a wrapper for XMLHttpRequest which was designed for fetching resources using the http protocol. However, it can support other protocols such as file, and ftp.
Second, CORS is not controlled by the browser, it's controlled by the http server. Cross domain origin requests can work, but only if the resource you are requesting responds with an http header that allows your domain to access it. Since the resource you are requesting has nothing to do with http, it will probably throw an error.
So why do images work using the file:// scheme? The <img/> tag supports loading resources using any scheme your browser cares to support. It turns out most browsers support it.
So I can't get json into my app without an http server!#? Yes and no. No because you usually cannot request a resource not served through an http server using XMLHttpRequest. However, you can still request resources through other means.
I recommend using the File API for reading files from the users filesystem.

Related

How can I load a local json file using d3?

I am trying to create a map and I have been using this tutorial https://newmedia.report/classes/coding/2018/mapping-in-d3/. I think the problem is that I can't load local files, but I am not sure how to fix it.
I have looked at other StackOverflow answers but keep getting the same problem. I tried setting up a dev server but it still isn't working. I also tried in firefox with the same code and got the error The Same Origin Policy disallows reading the remote resource at the file. (Reason: CORS request not HTTP). Then an error saying TypeError: NetworkError when attempting to fetch resource.
I am using all the same code from the tutorial but it isn't working.
Promise.all([
d3.json("ccc_precinct_topo.json"),
d3.csv("CCC_Primary_results.csv")
])
.then(function(data){
URL scheme must be "HTTP" or "HTTPS" for CORS request.
I keep getting an error like this for both files.
The recommended way would be to install a web server on your development system, e.g. XAMPP for a Windows or LAMP for a Linux system. Otherwise whenever you test something using AJAX calls you will run into problems of some sort.
Just for demonstration purposes you could save the JSON and CSV data as local variables. To do so, copy the contents of the JSON file "ccc_precinct_topo.json" into array data[0]:
var data= [];
data[0]= [...]; // contents of "ccc_precinct_topo.json"
In a second step, save the contents of the CSV file "CCC_Primary_results.csv" as a string into a new variable and use d3.csv.parse() to convert it into an array structure:
var csvContent= 'String|With|CSV|Values';
data[1]= d3.csv.parse(csvContent);
Now to see if you get correct values, send the data to the console:
console.log(data);
Open the Developer Tools (Hit F12) and refresh the page. In the Console section you should see an array with two elements, both should be array structures.
Instead of using Promises and d3.json(), d3.csv(), continue with the code you find below the .then(function(data){.
P.S. In most cases someone writing a tutorial about web services or pages assumes that the shown code will be used as part of a web project and thus will be loaded by a web server. But you are right, it could have been mentioned as a prerequisite, e.g. "Before you start, set up LAMP or XAMPP on your development system".

How to get file size from another site src?

So, guys, I get src's, from another site, and have the array like ["www.another.com/pic1.png", "www.another2.com/pic2.jpg"].
I tested XMLHttpRequest, and file.size, but CORS does not allow to do it.
How can I get file size, from this array items?
First of all, You must to resolve CORS problem. so you may can use a Node.js server as web crawler server to get data from another website.
Then you can use any tool which is can get detail of file to know the file size of the image.

HTML elements which also sends a cookie for crossDomain request?

One of the first earlier hacks of a major social website ( using old browser) was :
login to the site, so you got a cookie
create script tag which reference the "get friends list" url
override the array constructor via JS
and since the <script> tag does send a cookie , the request is authenticated and response with pure JSON (unrunnable) code - but since we override the array ctor , we can get the data.
That's fine ( that was a preview to my question).
Question
What is the complete list of elements which also send a cookie for a cross domain request ?
Wouldn't it be more accurate to say that any resource requested by the browser to a certain domain, would send the cookies in the request. So really, any elements that "loads" any resource from a server would have the cookies sent. So I'd say images, json files, html/php files, external CSS files and probably web fonts would send cookies. This could be one of the reasons why you would want to host your resources (scripts,CSS files, images) on another domain as an optimisation thing.
This JSFiddle is mostly a proof that CSS files can "remember".
HTML
<link href="remember.php?.css" rel="stylesheet"/>
Remember Red
Javascript
red.onclick=function(e){
var img=new Image()
img.src="remember.php?col=red"
return false
}
remember.php
if(isset($_GET["col"])){
$_SESSION["fav_color"]=$_GET["col"];
}
echo "body {
color:".htmlentities(#$_SESSION["fav_color"] ?: "blue")."
}";
So what should happen is that, when we load an image with URI remember.php?col=red, the server will remember that the color value even on refresh. Same principal with images and I would assume web fonts.
Another example are images. Which should send cookies, when loaded. Though, for example, stackoverflow.com hosts the images in another domain (in this case the layout stuff is on cdn.sstatic.net/stackoverflow/img/sprites.png ). And even if it did send, we wouldn't normally know if cookies was sent unless the cookie affects the image somehow. But if we check with the developer tools we would actually note that cookies do get sent. For example:
An image hosted on php.net
Same image on a different domain
As you can see, the cookies do get sent. Even when cross-domain. As further proof, the remember.php demo but with images.
Demo
HTML
<img src="http://mfirdaus.net/random/so/remember_image.php"/>
Toggle Image
Javascript
toggle.onclick=function(){
var img=new Image()
img.src="http://mfirdaus.net/random/so/remember_image.php?toggle"
img.onerror=function(){
window.location=window.location
}
return false
}
remember_image.php
if(isset($_GET["toggle"])){
$_SESSION["like_cats"]=!#$_SESSION["like_cats"];
die();
}
echo file_get_contents(#$_SESSION["like_cats"] ? "cat.jpeg" : "duck.jpeg" );
In this demo, the cookie does affect the image hence, it's easier to tell that the cookies get sent with images.
Now whether this resource contains privileged data (such as the JSON data that contains the friendlist) and the page calling this resource have the capability to use this privileged data (in this case, by doing magic javascript stuff to exploit the JSON) is another matter. Browsers should be safe enough that most of the obvious vectors should be secured. We can't even access other domain's images directly to put in canvases due to security. But of course there will be those pesky bugs and exploits for browser vendors to deal with.
I used to use this fact to make a Firefox extension that just scraped authenticated pages of a website to show a sidebar with parsed data, because ajax in Firefox extensions doesn't have the same-domain restrictions as normal pages, and I didn't have to bother to do anything special to authenticate because ajax sends the cookies as one would expect.

Getting dynamic content from a website through javascript

I am creating a firefox plugin and using javascript. I am using XMLHttpRequest to get dynamic content from a remote website and storing it into a file to parse it later. But in responseText i am not receiving any dynamic content. After storing information that i got is only the html page not having dynamic content.
code:
var res="";
var req = new XMLHttpRequest();
req.onload = function(){
res=this.responseText;
}
req.open("GET","www.ebay.com", true);
req.send();
It's can't be done due to same-origin policy, so you can only request content within the origin domain.
Here are some links may be helpful to you:
Getting CORS Working
Cross-domain Ajax with Cross-Origin Resource Sharing
Edit:
Since what you want to get from a website is generated by Ajax, so it's impossible to get the dynamic content. the dynamic content present on the website is after the browser loaded the html page and so the Javascript Event can be triggered to get the dynamic content through Ajax. You can get the html page, but you didn't get the Javascript files. therefor, Can't get the dynmic content.
sorry for my bad English
You can only fetch remote content under your own domain. This is a security issue. You can use JSONP, But for ebay I don't know if there are any json contents available. for more information have a look at this: http://www.devproconnections.com/article/aspnet2/ajax-cross-domain-142169
In the case you are using Javascript with a Chrome extension or a Firefox add-on, then you must set permissions in your manifest file to have access to those sites you want.

Load a remote XML into a web page and access its content via JavaScript

I'd like to know if it's possible to load a remote XML file through the <script> tag, and access the content using JavaScript.
As the XML is a result of an external website (I'm using TheTVDb API), I can't load it using AJAX.
I'm looking for something like the following, if it's possible (JQuery-like syntax):
<script id="xmlload" type="text/xml" src="...">
<script type="text/javascript">
var xmlcontent = $('#xmlload').content();
// parse xmlcontent
</script>
I don't think that this is possible - you will need to use XmlHttpRequest (AJAX) to use a HTTP-based API. However, it might still be possible to actually do cross-site requests if the TheTVDb server allows this - see HTTP access control on MDN, which describes the relevant W3C specification (Cross-Origin Resource Sharing).
So if you haven't done so yet, I'd recommend you just try if making an AJAX request works. Otherwise, it might be a good idea to ask the TheTVDb folks if they are so kind to implement the mentioned spec.

Categories