I am developing a web app that accesses some external JSON data. I'm currently using jQuery's getJSON to get the data and call the callback.
My internet at home is terrible, so I'm regularly not connected. I am looking for a way to develop this app while disconnected from the internet.
My initial thought was to have an OFFLINE variable that I set, which changes the location of the scripts to a local file, but because jQuery's getJSON uses dynamically named functions for callbacks, it would need some server intelligence.
More info on how getJSON callbacks work here: http://docs.jquery.com/Ajax/jQuery.getJSON
I'm sure there's an easier way. Any suggestions?
** Edit **
Let me try and clarify a bit
I'm currently running a local web server. I have to - script tags can't reference a local file, for security reasons.
I'm currently calling getJSON with the url: http://twitter.com/status/user_timeline/user.json?callback=?
If I downloaded that json response and hosted it on the local webserver, it wouldn't work, because the callback name will change every time, yet the feed will have the function name it was originally fetched with.
I have a similar problem. Try xampp for an easy php/apache/mysql install on your machine.
I use dreamhost to host my site. I manage everything with a subversion repository, which allows me to simply do 'svn update' on my live site when I am ready to pull in my changes.
I also define all my paths relative to a base_url variable, which is set depending on the http host, so I don't have to change anything for my site to run on different webservers. I use codeigniter, and my config file looks like this:
switch($_SERVER['HTTP_HOST']) {
case "claytonhp":
$config['base_url'] = "http://claytonhp/<project_url>";
break;
// etc.
}
To use that same path in my javascript, I put the following at the top of each html file:
<script type="text/javascript">
siteUrl = '<?= base_url();?>';
</script>
<script type="text/javascript" src="<?= base_url();?>public/scripts/external/jquery/jquery.js"></script>
<!-- Local functionality -->
<script type="text/javascript" src="<?= base_url();?>public/scripts/common.js"></script>
<!-- etc -->
Then, my jquery ajax calls look like this:
$.ajax({
type: "POST",
url: siteUrl + "index.php/ajax_controller/getSomeData",
dataType: "json",
data: "id=5",
success: successCallback,
error: errorCallback
});
Just use a web server (IIS is built into Windows, or use Apache, or XAMP otherwise). That way, you're always connected to your web site (use http://localhost/...).
Quick solution is to just run a local web server. This is a good idea for all sorts of reasons.
If you don't want to do that, just define the URL to get the JSON from somewhere global, and pass it to getJSON(). Just don't forget to set it back before you put your code up on the server.
I used a local sinatra webserver, and replaced the hosts in my /etc/hosts file. It's nice because it's super easy to define new services.
I often forget to reset my hosts file, which can cause a lot of frustration, so I created a script to wrap the whole thing as well.
Here's an example that will serve up a twitter user feed.
run.sh
#!/bin/bash
cp /etc/hosts /etc/hosts.original
cat offline_hosts >> /etc/hosts
ruby server.rb -p 80
cp /etc/hosts.original /etc/hosts
offline_hosts
127.0.0.1 twitter.com
server.rb
#!/usr/bin/ruby
require 'sinatra'
# twitter user
# http://twitter.com/status/user_timeline/$USER.json&callback=?
get '/status/user_timeline/:username.json', :host_name => /twitter\.com/ do
render_file "feeds/#{params[:username]}.json"
end
def render_file filename
output = File.open(filename).read
output = "#{params[:callback]}(#{output});" if params[:callback]
output
end
Related
So I have django project with jquery for interactivity in frontend. I already have .env file to store database configuration to be used by django settings.py, but I need jquery to be able to access the .env file too.
From what I read in dotenv documentation, I need to install the dotenv using npm or yarn. But I think jquery don't have/use npm? I am a newbie in javascript
Your script can't have access to .env, since it's running in your users' browsers.
First, if your API is hosted on the same domain as your page itself, you don't need to specify a hostname, just use relative URLs ('/api/v1/path/to/resource/'). That way your script doesn't need to know the host. Also, in Javascript, document.location will give you all the information about the current host.
Second, if it's not the same or you want other URL parameters to be set by Django for your script to use, set a variable in your template using a context variable. E.g. if your view fetches settings.API_URL and passes it as api_url to the context, you can do this in your template:
<script>var APIUrl = "{{ api_url }}"</script>
Then, as long as your jQuery script runs after this variable was defined, it will have access to it.
In Javascript, it is possible to load server-sided files via HTML or Javascript. I am trying to do the same thing except via an API call instead of a file directly (as this file is automatically generated).
I'm hosting a flask server that's being served to http://0.0.0.0:5000/ on a remote linux server, and I am able to make a GET request on the server via command line using wget http://localhost:5000/data and it will return the correct result.
However, if I try to make an ajax call on an html page it instead tries to GET data from my local computer's localhost rather than the server's localhost
For example, I have a simple index.html on the server, served by nginx:
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous">
</script>
<script>
var url = "http://127.0.0.1:5000/data"
$.ajax({
dataType: "json",
url: url,
success: function( data ) {
console.log(data)
}
});
</script>
But it doesn't seem to call on the server's localhost, and instead calls on the localhost of my computer. (i.e. it returns the results only if I am running the API service locally as well, and ERR_CONNECTION_REFUSED otherwise). How can I make it call on the "server"s localhost? Is this even possible to do?
An obvious workaround would be to process the file on the server and then save it to disk, and then call on the file directly via ajax, but I would like to avoid this if possible.
My server is pointed at localhost/_mainDir/. I need jsFile.js to access phpFile.php, however this is out of reach for jsFile.js.
How can I achieve this? I know that javaScript cannot access directories behind what the server is pointing to; however I do not want to change where my server is pointing due to security reasons.
Here's my directory structure:
projectDir -> _mainDir -> index.php
-> jsDir -> jsFile.js
-> phpFile.php
index.php:
<!DOCTYPE html>
<html>
<head>
<script src="jsDir/jsFile.js"></script>
</head>
</html>
jsFile.js:
$(document).ready(function() {
$.post("../../phpFile.php", {
x: 3
}, function(data) {
alert(data);
})
});
There are a couple of options.
You can setup a Symlink to that php file, as long as your webserver is setup to follow symlinks this would work - with that being said you may as well just move the file which will cause the same security issue you talk about.
You create another PHP file which the js file can communicate with, which then passes arguments to the ../../phpFile.php and handles the response from phpFile.php back to the $.post - that way your not exposing the phpFile.php and only the particular call made from the client side javascript.
Javscript calls from the front end can be somewhat controlled with CSRF tokens
http://bkcore.com/blog/code/nocsrf-php-class.html
This will allow you to include a CSRF token with the javascript call to the new file that proxies the request to phpFile.php
That way A. you know the request is coming from your frontend (CSRF), B. your only exposing what is required to the frontend.
EDIT: change POST, to arguments using $argv[0]
I have a python 2.7 app on Google Appengine. One of the JS files is served via a python script, not a standard static handler. The app.yaml config is shown below:
- url: /js/foo.js
script: python.js.write_javascript.app
secure: optional
The request for foo.js is part of a code snippet clients, of our service, place on their website, so it can't really be updated. python.js.write_javascript.app basically just reads in a JS template file, substitutes in a few customer specific values and prints to the browser.
What I'm wondering is, how do we set the correct headers so this request is cached correctly. Without any custom headers, appengine's default is to tell the browser never to cache this. This is obviously undesirable because it creates unnecessary load on our app.
Ideally, I would like to have browsers make a new request only when the template has been updated. Another option would be to cache per session.
Thanks
Well
It looks like Google handles this automatically. I just print it, using the correct JavaScript headers but without any cache headers and Google's CDN caches it for me. I'm not sure what the default cache lifetime is but I saw no increase in instances or cost by implementing this.
It seems Google just takes care of it for me.
I'm working on a script that reads an XML file and then outputs the data. It works perfectly when it runs on my web server, but won't run from my local machine. (The "542Data.xml" file is stored in the same folder as the HTML page on both the server and my computer, and I checked that all file versions are the same. I've tried it in Firefox and Chrome with the same results.)
<div id="output"></div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
$(document).ready(function()
{
$.ajax({
type: "GET",
url: "542Data.xml",
dataType: "xml",
success: parseXml
});
});
function parseXml(xml)
{
$(xml).find("point").each(function(index)
{
$("#output").append("Name: " + $(this).attr("name") + "<br />");
});
}
</script>
The XML is structured as:
<?xml version="1.0"?>
<destinations>
<point name="Tot Lot at Bryan Park">
<lat>39.15611</lat>
<long>-86.52664</long>
<type>outdoors</type>
</point>
<point name="Playground at Cascades Park">
<lat>39.19633</lat>
<long>-86.53581</long>
<type>outdoors</type>
</point>
</destinations>
What do I need to change to get this working locally?
EDIT: I was wrong, it's working in Firefox. (embarrassed!)
Your script works fine for me in Firefox.
Chrome has some security feature that disallows what you wanted to do (using file:/// for AJAX requests). You need to start your browser with:
chrome --disable-web-security
to disable security checks. (--allow-file-access-from-files might also do the trick, but I haven't tested it yet)
Warning: disabling security checks affects your browser security and should only be used for temporary development purposes. If you plan to run the code from your local machine in a prolonged period of time, consider installing a web server on your local machine.
If by "working locally" you mean you have the html and xml file in a folder and open the HTML file by double clicking on it, then there is no way.
In order for it to work locally you need an web server which will resolve http requests. Opening a local file on a file system is not what is happening here. .ajax() is making a server request. Without a server it won't work.
What are you using to develop? Check if the development server you are using can serve XML files.
According to the given (small) info. There is may be a security reason i.e. importing jquery from google's repository. Please give more code or look at the error console in firefox - ctr+shift+j and copy paste the error if there is any, or just download jquery and include it with path in local location.
It is running on server but not on your machine. See, the ajax request needs a local server running. To make it work, start some local server on your machine. For example, if you're on Windows, then download WAMP, and if on Linux, then install LAMP. Put your files in www folder. Then start the local server..and then access your file using localhost/your_file_name. That'll give you the result as you want it.