I'm doing a cross origin request to fetch a json response from the url which has a Basic authentication. So on tap of the button, am setting the headers for basic authentication. When I print out the values before the request has been sent I see them. But when i check the chrome dev tool for request I don't see the headers been set. Also the request turns to be an "Options" request from "GET" request and the response comes as 401 unauthorized. Is there anything am missing?
<paper-input type="search" value="{{imageUrl}}" placeholder="Enter Image URL"></paper-input>
<div class="buttons">
<paper-button on-tap="getData" autofocus>Search</paper-button>
</div>
<iron-ajax
id="xhr"
url="https://api.com/v1"
params='{"url":"some query value"}'
handle-as="json"
method="GET"
last-response="{{ajaxResponse}}"></iron-ajax>
getData: function(){
this.$.xhr.headers['X-Requested-With'] = "XMLHttpRequest";
this.$.xhr.headers['Authorization'] = this.makeHeaders(this.user, this.password);
this.$.xhr.generateRequest();
}
By default iron-ajax does not send the credentials by default for cross-site requests
You can change this by setting the withCredentials property on the iron-ajax:
<iron-ajax
id="xhr"
url="https://api.com/v1"
params='{"url":"some query value"}'
handle-as="json"
with-credentials="true"
method="GET"
last-response="{{ajaxResponse}}"></iron-ajax>
or
this.$.xhr.withCredentials = true;
Related
component html file part where request is being send
<paper-button class="indigo" style="margin-top:1em; width:15%"
on-tap="sendLoginRequest">Login</paper-button>
<iron-ajax id="loginAjaxRequest" handle-as="json" on-
response="loginResponse" on-error="showToast"></iron-ajax>
sendloginRequest function part where request is fired
sendLoginRequest() {
//some code
this.$.loginAjaxRequest.url = "http://localhost:8080/api/login"
this.$.loginAjaxRequest.body = JSON.stringify(loginJson)
this.$.loginAjaxRequest.method = "POST"
this.$.loginAjaxRequest.generateRequest()
}
how to write test cases for it
Currently I'm trying to send a post request to a server I have, which is configured to only accept JSON data.
Unfortunately, when I inspect the post request through the developer console of my browser, it sends the data not encoded as JSON, but as an encoded url so the response is of type 415, due to the discrepancy between expected type and provided data.
The form:
<form action='http://myhost.elasticbeanstalk.com/API/Beta/Register' method = 'post' enctype='application/json'>
Email: *<br>
<input type='text' name='Email' style='width: 500px;' value='{"Email":"test#gmail.com"}'><br>
<br>
(Fields denoted with * are mandatory)
<br>
<input type='submit' value='Apply' style='float: right;'>
</form>
As you can see, I should in theory send a request of content type json, however if you examine the request that gets sent, you see that the content type remains as an encoded url, yet the tag "enctype='application/json'" should fix that unless I'm mistaken.
(imgur is currently down, as usual, so I'll change this image to a more permanent link when possible)
https://puu.sh/unXtf/2610742d2f.png
Am I missing something?
Browsers natively do not support JSON as a media type with HTML. Use XMLHttpRequest/Ajax to submit your form as JSON. Dummy example using jQuery:
$.ajax({
url: 'http://yoururl',
type: 'POST',
data: yourFormDataSearilized
contentType: 'application/json', // this is what you want
success: function() {
// check
}
});
I'm using the latest Polymer (1.2.0), and I'm having trouble with databinding from iron-localstorage to the iron-ajax headers field. I'm not seeing the Authorization header set when I inspect the request. I've verified the request works when I just create a valid headers object with no databinding.
Am I doing something wrong, or is it not designed to be used like this?
<iron-localstorage name="userToken" value="{{localtoken}}" use-raw></iron-localstorage>
<iron-ajax url="api/twitter/v1/private/gettweets" last-response="{{data}}" auto
headers= '{"Authorization":"Bearer [[localtoken]]}"'
handle-as="json">
</iron-ajax>
<iron-list items="[[data.futuretweets]]" as="item">
<template>
<div>
datetime: <span>[[item.datetime]]</span>
text: <span>[[item.text]]</span>
</div>
</template>
</iron-list>
I think you have a typo error in your compound binding, here is a corrected version:
<iron-ajax url="api/twitter/v1/private/gettweets" last-response="{{data}}" auto
headers= '{"Authorization":"Bearer [[localtoken]]"}'
handle-as="json">
</iron-ajax>
[EDIT] since it is not working, try with a computed function like this:
<iron-ajax url="api/twitter/v1/private/gettweets" last-response="{{data}}" auto
headers='_computeHeaders(localtoken)'
handle-as="json">
</iron-ajax>
where
_computeHeaders(localtoken) {
return {"Authorization": "Bearer " + localtoken};
}
Shouldn't:
_computeHeaders(localtoken) {
return '{"Authorization":"Bearer ' + localtoken + '"}';
}
Instead be:
_computeHeaders: function(localtoken){
return '{"Authorization":"Bearer ' + localtoken + '"}';
}
I've found a little workaround.
I'm using loopback with authentication service enabled and I'm saving the authentication token with iron-localstorage. The problem I've found is that the "auto" of iron-ajax let start the request when any ( almost ) of the iron-ajax parameter change. When the request start the localstorage value hasn't been populated yet
<iron-localstorage name="appdata" value="{{user}}"></iron-localstorage>
and
<iron-ajax auto="{{user.id}}" headers$='{"Authorization" :"{{user.id}}"}' url="/api/data" handle-as="json" last-response="{{data}}"></iron-ajax>
the workaround is inside auto="{{user.id}}". While user isn't loaded the user.id is false. When loaded it become something that match as true. That cause also a change inside the iron-ajax header attribute and cause the "auto" request send to get fired.
I use Polymer Starter Kit 1.0.3.
My application have different types of pages. Some of them should render data received from request to backend API.
But when the application starts, all requests from all pages immediately start.
The question is how to do the right job with the backend?
I had the same problem as you, the solution I found was to use methods in my elements to call a function that it request information to the backend when I really need it. Sorry for my English.
There is iron-ajax,this is the mainly element polymer work with backend.
Here is an example in my project
<iron-ajax auto
verbose="true"
url="[[apiCategories]]"
handle-as="json"
on-response="_onCategoriesLoadComplete"></iron-ajax>
<iron-ajax auto
id="ajaxWeapons"
verbose="true"
url="[[apiWeapons]]"
params="[[apiWeaponsParams]]"
debounce-duration="300"
handle-as="json"
last-response="{{page}}"></iron-ajax>
<iron-ajax auto
verbose="true"
url="{{apiCountries}}"
handle-as="json"
last-response="{{countries}}"></iron-ajax>
This is very useful, when param change or id change, the whole page's data will reload, the simplest way to work with backend.
Maybe you don't want to auto request, example in my code
<iron-ajax id="ajaxUserRegister"
verbose="true"
url="{{apiUsers}}"
method="PUT"
on-response="_onUserRegisterComplete"
content-type="application/json"
handle-as="json"></iron-ajax>
<iron-ajax id="ajaxUserLogin"
verbose="true"
url="{{apiUsers}}"
method="POST"
on-response="_onUserLoginComplete"
content-type="application/json"
handle-as="json"></iron-ajax>
<iron-ajax id="ajaxUserGet"
verbose="true"
url="{{apiUsers}}"
method="GET"
headers="[[user.headers]]"
on-response="_onUserGetComplete"
content-type="application/json"
handle-as="json"></iron-ajax>
You can also use backend source when you needed
com._userLogin = function () {
var {inputAccount:account,inputPassword:pwd} = this;
if (!(account && account.length >= 4)) {
this.showToast('Wrong account');
return
}
if (!(pwd && pwd.length >= 4)) {
this.showToast('Wrong password');
return
}
this.$.ajaxUserLogin.body = {name: account, password: pwd};
this.$.ajaxUserLogin.generateRequest();
};
com._onUserLoginComplete = function (e, ajax) {
if (ajax.response.error) {
this.showToast('Login faield:' + ajax.response.error);
return
}
this.user = ajax.response;
};
In conclusion,define you backend resource as a iron-ajax, this is how polymer work with backend.
I have a form field (email signup) on the site, and the email provider wants me to submit it to their REST web service and get a response. I've never used JSON or AJAX before so floundering!
The HTML:
<form>
<input type="hidden" name="gid" value="12345678">
<input type="hidden" name="user.CustomAttribute.NewsletterPopUp" value="Global">
<input type="hidden" name="user.CustomAttribute.NewsletterOptIn" value="True">" value="True">
<input type="text" name="uemail" class="email_input_field" value="please enter your email" size="30" maxlength="64" onFocus="clearText(this)">
<input type="submit" name="signup" value="signup" class="email_submit_button">
</form>
Currently, using Javascript and using window.location to visit the URL (which creates the action instead of posting it) they want it converted to a form post action with XML response. What happens now:
$(".email_submit_button").click(function(){
var uemail = $('.email_input_field').val();
window.location = "http://example.com/automated/action.jsp?action=register&errorPage=/automated/action.jsp&gid=12345678&uemail="+uemail+"&user.CustomAttribute.NewsletterPopUp=Global&user.CustomAttribute.NewsletterOptIn=True";
return false;
}
});
I see you'r using jQuery so you can use the $.post to post to the server like this:
var url = "http://example.com/automated/action.jsp"
var data ={
"gid": form.gid,
"action": register,
"uemail": form.uemail,
"errorPage": "/automated/action.jsp",
"user.CustomAttribute.NewsletterOptIn": user.CustomAttribute.NewsletterOptIn,
"user.CustomAttribute.NewsletterPopUp": user.CustomAttribute.NewsletterPopUp
};
var success_func = function(data){
//do what you want with the returned data
};
$.post(url, data, success_func);
Documentation for $.post.
Or you can use the pure longer Ajax version it's mentioned in the documentation of the $.post.
EDIT:
I forget you can't do xhttpresuext to a different domain you need to use JSONP, here's a link to another SO post explaining everything by detail
Hope this help.
$(".email_submit_button").submit(function(e) {
// stop form from submitting
e.preventDefault();
// Grab all values
var uemail = $('.email_input_field').val();
// make a POST ajax call
$.ajax({
type: "POST",
url: "YOUR URL", // set your URL here
data: {
uemail: uemail // send along this data (can add more data separated by comma)
},
beforeSend: function ( xhr ) {
// maybe tell the user that the request is being processed
$("#status").show().html("<img src='images/preloader.gif' width='32' height='32' alt='processing...'>");
}
}).done(function( response ) {
// do something with the received data/response
//$("#status").html(response);
});
});
Not sure if ".email_submit_button" is the class given to the submit button or the form.. you need to use the id or class given to the form and not the submit button.. hope this helps