Ajax call to external URL - javascript

I am trying to access on or two data attributes from my personal Duolingo account. When punching in the following URL a JSON object is returned:
http://www.duolingo.com/users/username (I've replaced my id with "username" in the url).
var getDuolingoData = function() {
return $.ajax({
type: "get",
url: "http://www.duolingo.com/users/daniel692007&callback=?",
dataType: "json"
});
}
getDuolingoData().then(function(json) {
console.log(json.site_streak); // this log is causing the error
});
When I try and log a key from the returned object, however, the following error is logged to the console:
Uncaught SyntaxError: Unexpected token <
Ajax is fairly new to me, Duolingo don't have an API that I know of and as this is an external URL I believe the dataType must be set to jsonp due to CORS.
Is there an obvious reason that I am not able to access the JSON object I can see when visiting the specified URL?
TY

The same issue happened to me. I was unable to solve it using jsonp. What i ended up doing was to make an action in the controller that recieved the json from external url and send it to the ajax call.
For exmaple
return $.ajax({
type: "post",
url: "/ActionInProject/ProjectController",
});
then in the Controller it will be different for whichever server side language is being used. For me it was C# so i did something like
[HttpPost]
public JsonResult ActionInProject()
{
using(HttpClient client = new HttpClient())
{
var response = client.GetAsync("someothersite.com/api/link");
return Json(client.GetAsync());
}
}

I tried your request with Postman
and I found it not valid json in the respone you can find below what is returned of the server
<!DOCTYPE html><html dir="ltr"><head><title>Duolingo</title><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"><meta name="robots" content="NOODP"><noscript><meta http-equiv="refresh" content="0; url=/nojs/splash"></noscript><meta name="apple-mobile-web-app-capable" content="yes"><meta name="apple-mobile-web-app-status-bar-style" content="black"><meta name="apple-mobile-web-app-title" content="Duolingo"><meta name="google" content="notranslate"><meta name="mobile-web-app-capable" content="yes"><meta name="apple-itunes-app" content="app-id=570060128"><meta name="google-site-verification" content="nWyTCDRw4VJS_b6YSRZiFmmj56EawZpZMhHtKXt7lkU"><link rel="chrome-webstore-item" href="https://chrome.google.com/webstore/detail/aiahmijlpehemcpleichkcokhegllfjl"><link rel="apple-touch-icon" href="//d35aaqx5ub95lt.cloudfront.net/images/duolingo-touch-icon.png"><link rel="shortcut icon" type="image/x-icon" href="//d35aaqx5ub95lt.cloudfront.net/favicon.ico"><link href="//d35aaqx5ub95lt.cloudfront.net/css/ltr-9f45956e.css" rel="stylesheet"> <link rel="manifest" href="/gcm/manifest.json"></head><body><div id="root"></div><script>window.duo={"detUiLanguages":["en","es","pt","it","fr","de","ja","zs","zt","ko","ru","hi","hu","tr"],"troubleshootingForumId":647,"uiLanguage":"en","unsupportedDirections":[],"oldWebUrlWhitelist":["^/activity_stream$","^/admin_tools$","^/c/$","^/certification/","^/comment/","^/course/","^/course_announcement/","^/courses$","^/courses/","^/debug/","^/dictionary/","^/discussion$","^/event/","^/forgot_password$","^/guidelines$","^/help$","^/j$","^/mobile$","^/p/$","^/pm/","^/power_practice/","^/preview/.+/","^/quit_classroom_session","^/redirect/","^/referred","^/register_user$","^/reset_password","^/settings/reset_lang","^/skill_practice/","^/team/","^/teams$","^/topic/","^/translation/","^/translations$","^/translations/","^/troubleshooting$","^/ui_strings/","^/upload$","^/vocab","^/welcome$","^/welcome/","^/word","^/words$"]}</script><script>window.duo.version="c89bfb9"</script><script>!function(r){function n(t){if(e[t])return e[t].exports;var s=e[t]={i:t,l:!1,exports:{}};return r[t].call(s.exports,s,s.exports,n),s.l=!0,s.exports}var t=window.webpackJsonp;window.webpackJsonp=function(e,i,o){for(var c,a,f,d=0,u=[];d<e.length;d++)a=e[d],s[a]&&u.push(s[a][0]),s[a]=0;for(c in i)Object.prototype.hasOwnProperty.call(i,c)&&(r[c]=i[c]);for(t&&t(e,i,o);u.length;)u.shift()();if(o)for(d=0;d<o.length;d++)f=n(n.s=o[d]);return f};var e={},s={31:0};n.e=function(r){function t(){c.onerror=c.onload=null,clearTimeout(a);var n=s[r];0!==n&&(n&&n[1](new Error("Loading chunk "+r+" failed.")),s[r]=void 0)}var e=s[r];if(0===e)return new Promise(function(r){r()});if(e)return e[2];var i=new Promise(function(n,t){e=s[r]=[n,t]});e[2]=i;var o=document.getElementsByTagName("head")[0],c=document.createElement("script");c.type="text/javascript",c.charset="utf-8",c.async=!0,c.timeout=12e4,n.nc&&c.setAttribute("nonce",n.nc),c.src=n.p+""+({0:"js/vendor",1:"js/app",2:"strings/zh-TW",3:"strings/zh-CN",4:"strings/vi",5:"strings/uk",6:"strings/tr",7:"strings/tl",8:"strings/th",9:"strings/te",10:"strings/ta",11:"strings/ru",12:"strings/ro",13:"strings/pt",14:"strings/pl",15:"strings/pa",16:"strings/nl-NL",17:"strings/ko",18:"strings/ja",19:"strings/it",20:"strings/id",21:"strings/hu",22:"strings/hi",23:"strings/fr",24:"strings/es",25:"strings/en",26:"strings/el",27:"strings/de",28:"strings/cs",29:"strings/bn",30:"strings/ar"}[r]||r)+"-"+{0:"2b9feda7",1:"662ee5e7",2:"c444b0a9",3:"a5658bf8",4:"3ea447d8",5:"1573893a",6:"c32ed883",7:"52cac8bc",8:"2c58adbb",9:"681aaba6",10:"d05b78c6",11:"f4071afb",12:"a1349f5c",13:"6a57ec9f",14:"762dfc94",15:"8a02897a",16:"4e429b1e",17:"8e921ddf",18:"524cc86b",19:"8df42324",20:"7d8a8fc5",21:"4fde5d79",22:"509b8809",23:"9f09bcfb",24:"77da48d4",25:"44cfb321",26:"13b268cc",27:"c0cac402",28:"3ecdeec1",29:"dfd2b224",30:"074ffddd"}[r]+".js";var a=setTimeout(t,12e4);return c.onerror=c.onload=t,o.appendChild(c),i},n.m=r,n.c=e,n.d=function(r,t,e){n.o(r,t)||Object.defineProperty(r,t,{configurable:!1,enumerable:!0,get:e})},n.n=function(r){var t=r&&r.__esModule?function(){return r.default}:function(){return r};return n.d(t,"a",t),t},n.o=function(r,n){return Object.prototype.hasOwnProperty.call(r,n)},n.p="/",n.oe=function(r){throw console.error(r),r}}([])</script><script src="//d35aaqx5ub95lt.cloudfront.net/js/vendor-2b9feda7.js"></script> <script src="//d35aaqx5ub95lt.cloudfront.net/strings/en-44cfb321.js"></script> <script src="//d35aaqx5ub95lt.cloudfront.net/js/app-662ee5e7.js"></script></body></html>
as you can see the JSON is wrapped inside a HTML page which is not valid JSON syntax it something related to the API itself. it returns a page instead of JSON object .

Related

Passing a JS variable to Flask API URL

I made an API using Flask that has a url of this format
localhost:5000/data/?query=<Query Goes Here>
This API basically just returns a webapage with this small json:
{
"text" : "(Whatever we entered in the URL)"
}
I wanted to know how we can pass a Node.js variable to the URL ?
If it is not possible, how can I make an API in Python that
Takes input in JS -> Sends it to Python for Processing -> Sends output back to JS OR Displays a rendered page with that output
I can answer you with this example.
Takes input in JS :
JS file :
$("#test_enable").on('click', function(e) {
$this = $(this)
var test_id = $("#test_id_generator").val(); # get a value from test_id_generator
$.ajax({
url: url,
type: 'POST',
data: {
'test_id': test_id,
},
success: function (data) {
location.reload(true)
}
});}
python file:
def product_register_disable(request):
test_id = request.POST.get('test_id')
Sends output back to JS OR Displays a rendered page with that output
you can show the value using JINJA2 and python
python side
#routes.route('/showtime', methods=["GET", "POST"])
def showtime():
return render_template('showtime.html', value = 'testtest')
HTML side
<!DOCTYPE html>
<html lang="en">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js">
</script>
meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<head>
<body>
<div>{{value}}</div>
I hope I help.

Sending query string parameters to php via fetch not working [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I simply want to send a query string parameter to a (same page) php script via the fetch api. The purpose is so that I can store a variable that exists in javascript inside a php $_SESSION variable instead. But it's not working.
Background: I wrote some javascript that detected which radio button out of several was toggled on. The value of this radio button stores the name of a PHP template that I wanted to load as an SSI from a database.
So I don't really want to manipulate the response in javascript, I just want to be able to pass the variable (hardcoded in this example, but intended to come from a javascript variable) to PHP $_GET or $_POST.
Thanks to people who have answered so far.
Code below:
<?php
if(isset ($_REQUEST['name'])){
echo "The name param is received!";
}
else {
echo "The name param is NOT received!";
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home</title>
</head>
<body>
<script>
fetch('index.php?name=matt');
</script>
</body>
</html>
I recommend you take a look at the MDN Fetch() API documentation. Your fetch() is missing its headers, its method, a response resolution (first .then()), and a result resolution (second .then()).
But, you MIGHT NOT WANT to use fetch(). Fetch returns the result of the page to the JavaScript, not to the user. The way you're using it, it looks like you just want the user to go to that page directly (in which case, just <a href='?name=matt'>Click Me</a>).
Ultimately, I think you need to understand that the purpose of fetch() is to send data to the JS environment, not to reload the page for the user. Anyway, here's how your call would look if it worked...
<script>
fetch('index.php?name=matt', {
'headers': {
'Accept': 'text/html',
'Content-Type': 'text/html'
},
'method':'GET',
'body':'',
})
.then((response) => response.text())
.then((responseText)=>{
console.info("Response?");
console.info(responseText); // result: "The name param is received!...(and the rest of your page)
});
</script>
If you wanted to have fetch() return $_GET and/or $_POST variables to the JS in a usable fashion, then welcome JSON and json_encode() into your heart.
Make a new PHP script, userdata.php, and code it as so...
<?php
header('Content-Type: application/json'); // send JSON header, let page know it's JSON
print(json_encode(['name':$_POST['name']])); // get the name
?>
With this, update your above JS to be...
fetch('http://www.example.com/your/script.php', {
'headers': {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
'method':'POST',
'body':JSON.stringify({'name':'matt'}),
})
.then((response) => response.json())
.then((responseJson)=>{
console.info("Response?");
console.info(responseJson);
});
Notice what I have changed above: I made it use the POST method, which gives you a cleaner way of sending the data (namely using body, instead of appending it onto the URL, like '?...'). Your response, also, is .json()'d, and not .text()d.

How to call php function from JavaScript using Ajax?

In my Wordpress site, I want to create a dropdown menu with all the tags, but since it has more then 7.000, it needs to load only after the user click. I now it is only possible using Ajax, and I have started, but not accomplished yet.
http://jsfiddle.net/7kf1r9vw/2/
In this Fiddle, after the click, this javascript file is loaded:
/echo/js/?js=hello%20world!.
The second example in Fiddle is just to show my actual code. I want that the results populated by the php funcion only starts after the user click.
But I don't know how to change it to a PHP function. Also, is it possible to add plain PHP script in the output or only with it embedded in a file?
As Draco18s said, in your case, Javascript is executed client-side and PHP is executed server side.
In this case what you can do is a request to the server using Ajax.
For example, if you have the following html:
<select name="tag-dropdown" id="selectTags">
<option value="#">Select an artist</option>
</select>
You can use Ajax to make a POST request to a PHP script:
$( document ).ready(function() {
$.ajax({ url: 'merge2.php',
data: {operationName: "tagsNames"},
type: 'post',
success: function(output) {
tagNamesres = JSON.parse(output);
jQuery.each(tagNamesres, function(name, val) {
$("#selectTags").append('<option value="'+val+'">'+name+'</option>');
});
}
});
});
The PHP script can contain something like:
<?php
if (isset($_POST['operationName']) && !empty($_POST['operationName']) && $_POST["operationName"]=="tagsNames") {
$resultarray = array();
$resultarray["tagName1"] = "tagValue";
$resultarray["tagName2"] = "tagValue2";
echo json_encode($resultarray);
return;
}
?>
In order to return something from the PHP function you need to print or use echo.
This is just an example so you could start working with this :)
For more information about how Ajax request works, read this http://thisinterestsme.com/simple-ajax-request-example-jquery-php/
Your question appears to be "how do I call a php function on the server from my browser javascript code". In your code, you have the following function where the first parameter is the server side request:
function getSuccessOutput() {
getRequest(
'/echo/js/?js=hello%20world!', // demo-only URL
drawOutput,
);
return false;
}
To change that to call a server php routine, you would change '/echo/js/?js=hello%20world!' to the url on your server you want to have executed: e.g. '/myPHPFolder/someRoutine.php' . The results will be delivered back to your req object.
In your initial html file (e.g. index.html, or where ever you start your flow), include the onload option on the body tag:
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="yada yada yada">
<meta name="author" content="you">
<title>title for browser tab</title>
</head>
<body class="tutorial" onLoad="initPage()">
<select id="optionList"></select>
</body>
</html>
This tells the browser to run the "initPage()" function with no parameters. The initPage() function then issues an async call and loads up your data, perhaps saving it to a local variable in the process.
function initPage()
{
$('#optionList').empty(); // this ensures that you don't duplicate the info in the select list.
$.when($.get('/myPHPFolder/someRoutine.php').done(function(res)
{ // if of interest, save the results to a cookie or variable.
// you could also include a check to see if the data has already been downloaded.
// This is a 'happy path' example, which does not include error checking from the host
// build the optionList select HTML element
for (let each in res)
{(function(_idx, _arr)
{
// append the correct value to the select list.
// this example is based on returning a JSON object with an
// element called "id" which has the value I want to display in the options list
$('#optionList').append('<option value="'+_arr[_idx].id+'">' +_arr[_idx].id+'</option>');})(each, res);
}
// create a function to execute when the user selects a different buyer
$('#buyer').on('change', function() { /* do something useful here */ });
}
}

Parsing Json data in JQuery/Javascript

I saw a similar discussion here. But my returned data format is a bit different.
I have a Json string returned from server as shown below
<!DOCTYPE HTML>
<html>
<head>
<style>
</style>
</head>
<body>
{"error":false}</body>
</html>
I need to extract data "error":false from the Json string.
I tried as below
(1)Say the Json message is in result variable, then I checked as
if(result.error == false)
It doesn't work.
(2) I also used jQuery.parseJSON as discussed in this link.
It doesn't work also.
How can I parse Json data?
Json data is parsed in Jquery.ajax for the returned message as follow
jQuery.ajax({
url: "registrationdatavalidationatserver.php",
type: "POST",
data: $("form").serialize(), /*grab all elements in your form and serialize them */
success: function(result){
//To parse result
},
error: function(){
// the AJAX request failed as in timed out / bad url etc.
}
});
(3) How to return message from server just Json data without
<html>, <head>, <style>, etc. tags?
I returned from server as echo json_encode($data);
I have a Json string returned from server as shown below.
No, you need to have only the following returned from the server:
{"error": false}
Say the Json message is in result variable, then I checked as if(result.error == false)
It will never work because it is a HTML. Not a JSON.
How to return message from server just Json data without <html>, <head>
Even before you send the output, please make sure you are not sending anything to browser. Have these defined in the PHP headers:
<?php
header("Content-type: application/json");
die(json_encode($arrayData));
?>
There must not be anything other than this. It is wise to have a dedicated file for JSON output too, if you are confused in making this kind of setup.

Protecting against XSS with dynamically generated JavaScript

I have to pass a jQuery plugin some data. I could either pass it a URL where it will use a GET request to fetch the data, or directly pass it an array which will eliminate one server request. The data in question is user provided and not sanitized upon database entry.
The below script doesn't show the plugin, but does show how I might pass the data to the client so it may be directly passed to the plugin. As seen, the dynamically generated JS approach is suspect to XSS, however, the Ajax/JSON approach doesn't seem to be.
For this scenario, how should the dynamically generated JavaScript approach be secured, and is there risk to the Ajax/JSON approach?
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>XSS Testing</title>
<script src="getStuff.php?type=js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.js" type="text/javascript"></script>
<script type="text/javascript">
$(function(){
console.log(stuff);
$.get( "getStuff.php", function( data ) {
console.log(data);
},'json');
});
</script>
</head>
<body>
</body>
</html>
getStuff.php
<?php
$getFromDB=array(
'Mary',
'x"];alert(\'xss2\');x=["x',
'John'
);
if(isset($_GET['type']) && $_GET['type']=='js') {
header('Content-Type: application/javascript;');
$s='var stuff=[';
foreach($getFromDB as $row) {
$s.='"'.$row.'",';
}
$s=substr($s, 0, -1).'];';
echo($s);
}
else {
header('Content-Type: application/json;');
echo(json_encode($getFromDB));
}
?>
if you expect to work with JSON, why not first and foremost verify that's what you're working with?
$.get(...)
.success(function(data) {
try {
JSON.parse(data)
} catch (e) {
console.error("this isn't actually JSON");
}
})
JSON cannot contain functions, nor function calls, so just asking the browser to see if it can be parsed should be enough to make it go "there is stuff in here that isn't real JSON data".
The same goes for your PHP of course. Never build a string if you need a specific serialization. In this case, construct your key/map object the usual PHP way, and then use the built in json_encode function for converting that to a legal JSON serialization, instead.
It's almost like you've designed your example to be susceptible to hacking. You're doing nothing in the "js" case to ensure that the data is output with proper escaping, you're only doing it in the "json" case.
If you're going to include a JavaScript file that's purely data, like this:
<script src="getStuff.php?type=js"></script>
Then getStuff.php needs to ensure what it sends back is properly escaped as data:
<?php
$getFromDB=array(
'Mary',
'x"];alert(\'xss2\');x=["x',
'John'
);
if(isset($_GET['type']) && $_GET['type']=='js') {
header('Content-Type: application/javascript');
echo('var data = ');
echo(json_encode($getFromDB));
echo(';');
}
else {
header('Content-Type: application/json');
echo(json_encode($getFromDB));
}
?>
And boom: No alert.
Side note: You shouldn't have the ; on the end of the Content-Type strings. I've removed them in the above.

Categories

Resources