How to read JSON response from Google web services in Javascript? - javascript

I am trying to find the distance between two locations. For that I used Google web services. I got a JSON response from that web service, but I am unable to get the distance from that JSON response in a javascript function.
See my code below:
function myjourneysubdetails(){
var fp = jQuery('#fp').val();
var tp = jQuery('#tp').val();
var city = jQuery('#city').val();
alert(fp);
$.ajax({
type : 'GET',
url : 'http://maps.googleapis.com/maps/api/distancematrix/json?origins=Silk board&destinations=marathahalli&language=en-US&sensor=false',
async: false,
success : function(data) {
alert("Success");
var locObject = eval('(' + JSON.stringify(data) + ')');
alert("locObject: "+locObject);
alert("Destination: "+locObject.destination_addresses);
var origins = data.origin_addresses;
var destinations = data.destination_addresses;
alert('destinations'+destinations);
for (var i = 0; i < origins.length; i++) {
var results = data.rows[i].elements;
for (var j = 0; j < results.length; j++) {
var element = results[j];
var distance = element.distance.text;
var duration = element.duration.text;
var from = origins[i];
var to = destinations[j];
alert('distance'+distance);
}
}
},
error : function(xhr, type) {
alert('Internal Error Occoured! '+xhr+' : '+type);
}
});
}
Thanks in advance.

The problem you're having is called the "same origin policy" of web browsers.
Basically, as one of numerous security measures implemented by web browsers (and one of the earliest to be proposed and implemented) you are not allowed to make ajax requests to a domain which is different from the url of the web page. So, the only way for your code to work as is is if you can manage to convince google to host your page on the maps.googleapis.com domain.
Obviously that won't work. There are several work-arounds to this. The current most popular method is JSONP. Unfortunately google maps does not support JSONP. There are several other methods such as using flash or java applets to forward the request for you. But the simplest, most compatible method is the original solution to this problem: proxy the request on your server.
The reason proxying works is because programming languages and web servers, unlike web browsers, don't care where you connect to on the internet. There are several ways you can do this. You can either write a web app to do the proxying (an example is this simple proxy in PHP: https://github.com/cowboy/php-simple-proxy/) or configure your web server to proxy your request (for example using apache mod_proxy or mod_rewrite) or you can use a dedicated proxy server installed on your server.
So for example, in your code you should really be doing this:
$.ajax({
type : 'GET',
url : 'http://myserver.com/proxy/distancematrix/json?origins=Silk board&destinations=marathahalli&language=en-US&sensor=false',
And then configure your server to forward that request with something like this:
# Example of Apache mod_rewrite proxying:
RewriteEngine on
RewriteRule ^/proxy/(.*) http://maps.googleapis.com/maps/api/$1 [P]
A word of warning:
However you do it, remember that this is the internet. Do not write an open proxy. If you do you run the risk of hackers using your proxy to forward spam, DOS attacks etc. and you'll get the blame because it would appear to come from your server. The best way to prevent this is to hardcode the proxy url to google maps so that people can't use your server to connect to anywhere else. Just forward the query parameters, not the whole url.

Related

By-pass virus scan for Google Drive links and get the confirm ID

With some help from this thread I came up with the code below. How can I fetch the Google Drive file ID, open the direct link to the file and snatch the virus scan confirm ID that is required to stream files over 100 MB and then puzzle back the link? I'm kind of stuck at the xhr part.
function fixGoogleDriveURL(url) {
if (url.indexOf('drive.google.com') !== -1) {
var DocIDfull = url;
var DocIDstart = DocIDfull.indexOf('open?id=');
if (DocIDstart == -1) {
// invalid
return url;
}
var DocID = DocIDfull.slice(DocIDstart+8);
url = 'https://drive.google.com/uc?export=download&id=' + DocID;
var xhr = new XMLHttpRequest();
xhr.onload = function () {
if (xhr.readyState === xhr.DONE) {
if (xhr.status === 200) {
var token = xhr.responseText.match("/confirm=([0-9A-Za-z]+)&/");
window.location.replace(url + '&confirm=' + token[1]);
// should I add url += '&confirm=' + token[1] here instead of window.location?
}
}
};
xhr.open("GET", url);
xhr.send();
}
return url;
}
console.log(fixGoogleDriveURL('https://drive.google.com/open?id=1C25uoL6nIqqNhex3wm8VwODsO2q2pXBt') + "\n<-- should output:\nhttps://drive.google.com/uc?export=download&id=1C25uoL6nIqqNhex3wm8VwODsO2q2pXBt&confirm=XXXXX");
Scraping GDrive using Client-Side JavaScript isn't explicitly allowed by Google and therefore your Ajax call/XHR fails.
The only way to get around that restriction is by using a proxy in the middle that will forward Google's Website code but add appropriate Access-Control Allow-Origin Headers.
You can either use your own server for that (some minimal server-side script code will do) or you can use a service like http://multiverso.me/AllOrigins/ or https://corsproxy.github.io/ to proxy the request for you.
The AllOrigins site has some example code for use with jQuery, but basically they work by URI encoding the URL you want to access and appending that string to the site's proxy URL.
Here's an article by freecodecamp.org that outlines how to use these services (skip to the Don’t Let CORS Stop You! section.
Note: A security advice: These services are working fine right now, but they could go out of business tomorrow and start serving malicious data instead or redirect your file requests to completely different files or completely different websites altogether. It's up to you to decide if you want to trust these strangers or not.

Chrome Extensions: use chrome.webRequest to modify HTTP request equivalent of the `--data` arg of a cURL request

Diving into my first chrome extension, and trying to figure out how to modify some data in http requests.
I'm using the documentation here: https://developer.chrome.com/extensions/webRequest
I was able to setup the extension to listen for requests, but am not able to access the data I want.
When I'm in the chrome dev tools, on the Network tab, I right click the particular request I'm trying to modify and copy as cURL. The data I want to modify shows up after --data. I want to access this and change an integer value one of the parameters is set to.
I'm not sure what the equivalent is with these http requests, but I've tried the following:
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
var bkg = chrome.extension.getBackgroundPage();
bkg.console.log("onBeforeRequest");
bkg.console.log(JSON.stringify(details));
blockingResponse = {};
return blockingResponse;
},
{urls: [/*URL*/]},
['requestBody','blocking']
);
I can find the request with the url that I am looking at in the Network tab of the dev tools, so I'll be able to parse that and make sure I'm only modifying the requests that I want to, but printing the details doesn't show the data that I actually want to modify. Any idea how to obtain the HTTP request equivalent of the --data argument of a cURL request? And, well, modify it.
Edit: Here's the progress I've made.
When I log those details, I get ..."requestBody":{"raw":[{"bytes":{}}]},...
However, if I change onBeforeRequest to:
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
var bkg = chrome.extension.getBackgroundPage();
bkg.console.log("onBeforeRequest");
bkg.console.log(JSON.stringify(details));
var encodedData = getBase64FromArrayBuffer(details.requestBody.raw[0].bytes);
bkg.console.log("unencoded data: " + details.requestBody.raw[0].bytes);
bkg.console.log("encodedData: " + encodedData);
blockingResponse = {};
return blockingResponse;
},
{urls: ["*://*.facebook.com/*"], types: ["xmlhttprequest"]},
['requestBody','blocking']
);
function getBase64FromArrayBuffer(responseData) {
var uInt8Array = new Uint8Array(responseData);
var i = uInt8Array.length;
var binaryString = new Array(i);
while (i--)
{
binaryString[i] = String.fromCharCode(uInt8Array[i]);
}
var data = binaryString.join('');
var base64 = window.btoa(data);
return base64;
}
The encoded data exists, showing a long string of chars, though it's gibberish. Does this mean that I won't be able to access this data and modify it? Or is there a way to decode this data?
The chrome.webRequest API does allow you to access POST data. It does not, however, allow you to modify the POST data.
You are able to modify some of the header info, but not the POST data.
It appears the ability to modify POST data was intended, but a dev at Google who was working on it got moved to something else, and sat on the bug/feature request for two years afterwards, and just released it so someone else could pick it up a few months ago. If this is a feature that interests you, head to https://bugs.chromium.org/p/chromium/issues/detail?id=91191# and star this bug (requires gmail account), and perhaps some renewed interest will lead to someone completing the functionality.

error 401 : unauthorized, received even after using API key while using www.openweathermap.org

Hi I am buliding my first web app using javascript and fetching data using API from www.openweathermap.org/
I have used the API key as mentioned in the documentation still it is giving an error of unauthorization. Can there be any other reason for this error while calling a function or so . Thank you in advance.
var APPID = "my_secret_key";
var temp;
var loc;
var icon;
var wind;
var humidity;
var direction;
function updateByZip(zip){
var url = "http://api.openweathermap.org/data/2.5/weather?" +
"zip = " + zip +
"&APPID =" + APPID ;
sendRequest(url);
}
function sendRequest(url){
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
var data = JSON.parse(xmlhttp.responseText) ;
var weather = {};
weather.wind = data.wind.speed;
weather.direction = data.wind.deg;
weather.loc = data.name;
weather.temp = data.main.temp;
weather.icon = data.weather[0].id;
weather.humidity=data.main.humidity;
update(weather);
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
It's the spaces near the equal signs in your URL. It's likely urlencoding the space and sending your parameter as APPID%20 which is not being recognized as valid.
var url = "http://api.openweathermap.org/data/2.5/weather?" +
"zip=" + zip +
"&APPID=" + APPID;
for future users, as i was having 401 error but solved it differently.
Error:
Invalid API key. Please see http://openweathermap.org/faq#error401 for more info
API calls responds with 401 error:
You can get the error 401 in the following cases:
You did not specify your API key in API request.
Your API key is not activated yet. Within the next couple of hours, it will be activated and ready to use.
You are using wrong API key in API request. Please, check your right API key in personal account.
You have free subscription and try to get access to our paid services (for example, 16 days/daily forecast API, any historical weather data, Weather maps 2.0, etc). Please, check your tariff in your [personal account]([price and condition]).
here are some steps to find problem.
1) Check if API key is activated
some API services provide key information in dashboard whether its activated, expired etc. openWeatherMap don't.
to verify whether your key is working 'MAKE API CALL FROM BROWSER'
api.openweathermap.org/data/2.5/weather?q=peshawar&appid=API_key
replace API_key with your own key, if you get data successfully then your key is activated otherwise wait for few hours to get key activated.
2) Check .env for typos & syntax
.env is file which is used to hide credentials such as API_KEY in server side code.
make sure your .env file variables are using correct syntax which is
NAME=VALUE
API_KEY=djgkv43439d90bkckcs
no semicolon, quotes etc
3) Check request URL
check request url where API call will be made , make sure
It doesn't have spaces, braces etc
correct according to URL encoding
correct according to API documentation
4) Debug using dotenv:
to know if you dotenv package is parsing API key correctly use the following code
const result = dotenv.config()
if (result.error) {
throw result.error
}
console.log(result.parsed)
this code checks if .env file variables are being parsed, it will print API_KEY value if its been parsed otherwise will print error which occur while parsing.
Hopefully it helps :)
Others suggestion
5) Check location of .env file
look for location of .env file in your directory, moving it to root directory might help (suggested in comments)
For those who followed the previous answers and are still facing the 401 issue: it seems it is now required to access the the API via HTTPS --- at least that's the case for me. Some older guides and tutorials might continue to use http:// in their code, so you'll have to change it to https://.
As far as I know, there is no mention of this in OpenWeather's official docs, and they don't include the protocol in their examples too.

Deconstruct/decode Websocket frames like Google Chrome does

I'm connecting to a website via websocket connection (client to server), I know how to encode the data and write it to the server (using the net module in node.js) but when I'm reading the data back I get odd characters in front of the important data, like if I'm suppose to get:
// Data needed on the left and data I'm receiving from websocket on the right
'inited\r\n' -> '�inited\r\n'
'n:2\r\n' -> '�n:2\r\n'
This is how I am getting the data from the server
Klass.prototype.connect = function(){
// this.port is equal to 8080 and the exact server varys, but it's not that important anyways since the problem is decoding the data properly.
var that = this;
var buffer = "";
this.socket = new net.createConnection(this.port, this.server);
this.socket
.on("connect", function(){
that.sendHandshake(); // just sends a standard client to server handshake
})
.on("data", function(recv){
// .split('\r\n\r\n').join('\r\n') needed to separate the server handshake from the data I am trying to parse
buffer += recv.toString('utf-8').split('\r\n\r\n').join('\r\n');
while (buffer){
var offset = buffer.indexOf('\r\n');
if (offset < 0)
return;
var msg = buffer.slice(0, offset);
// parseMsg(msg)
buffer = buffer.slice(offset + 3);
}
});
};
I am probably doing a lot of things improperly in the code above, but I'm not quite sure how to do it exactly so that is the best I got for now.
Problem is I don't know how to remove the mystery/special characters. Sometimes there is only 1 mystery/special character, but other times there is multiple ones depending on the data but they are never after the important data I need to check.
When I use Google Chrome and view the data on through tools->JavaScript console->network tab and find the websocket stream I'm looking for Google parses it correctly. I know it's possible since Google Chrome shows the correct frames, how do I deconstruct/decode the data so I can view the correct frames on the terminal?
I don't really need it in a particular language as long as it works I should be able to port it, but I would prefer examples/answers in node.js since that is the programming language I am using to connect to the server.

How to get a password encrypted since the Java Script file in my web application?

I'm designing some code for a standard login in a web application, I consider that doing the password encryption on client side is better than making mongo server doing it.
So, if I have this code ...
$("#btnSignUp").click( function () {
var sign = {
user:$("#signUser").val(),
pass:$("#signPass").val()
};
});
And then I'd do a post of sign with the password value already encrypted, how could I achieve this? Does JavaScript support AES?
You should submit the login page over https and make use of certificates to do the encryption. JavaScript is never a good idea for things that need security since you can control/influence the execution of it using developer tools built into most browsers
There are many libraries available for javascript to encrypt your data. Check out http://crypto.stanford.edu/sjcl/
I'd recommend using AES encryption in your JavaScript code. See Javascript AES encryption for libraries and links. The trouble you'll have is picking a key that is only available on the client side. Perhaps you can prompt the user? Or hash together some client system information that's not sent to the server.
kindly refer this link
http://point-at-infinity.org/jsaes/
AES_Init();
var block = new Array(16);
for(var i = 0; i < 16; i++)
block[i] = 0x11 * i;
var key = new Array(32);
for(var i = 0; i < 32; i++)
key[i] = i;
AES_ExpandKey(key);
AES_Encrypt(block, key);
AES_Done();

Categories

Resources