The following code snippet is used by a coworker to get an URL from a DB and then submit a "virtual" form to that URL.
$.ajax({
url: location.origin + location.pathname + "data/getURL.php",
method: "POST",
data: {
userName: user
},
success: function( data : any, textStatus : string, jqXHR : JQueryXHR){
console.log(data);
var url = (JSON.parse(data)).url;
if(url !== undefined && url !== null && url !== ""){
var sender : HTMLFormElement = document.createElement("form");
sender.setAttribute("action", `http://${url}/receive`);
sender.setAttribute("method", "POST");
var userSenderField = document.createElement("input");
userSenderField.setAttribute("type", "hidden");
userSenderField.setAttribute("name", "user");
userSenderField.setAttribute("value", user);
sender.appendChild(userSenderField);
var passSenderField = document.createElement("input");
passSenderField.setAttribute("type", "hidden");
passSenderField.setAttribute("name", "password");
passSenderField.setAttribute("value", password);
sender.appendChild(passSenderField);
document.body.appendChild(sender);
sender.submit();
Using either Burp Suite or just Chrome's Dev Tools, I can see the call to getURL.php but then I can't see the call to http://url/receive. Why?
For the sake of argument, let's say your ajax call to data/getURL.php succeeded, but delivered bad or unexpected data.
You then end up in your ajax call's success handler.
The success handler immediately creates a new form, populates it with (the bad) data, and submits the form.
This causes a postback to happen.
Chrome's dev tools clear the network panel upon postback by default, also clearing the call to "data/getURL.php", so you never actually saw the call succeed, and could not see in the net panel what it did. (ergo, you had no idea that data/getURL.php delivered the wrong data to you.
if you put a breakpoint in your ajax success handler before it submits the form, you can actually see what is going on.
Related
I'm building a Web App and I am required to make some form of Cross-Domain POST request to a server which I don't personally have access to.
I've tried many things to make it work with Ajax but I found no success. I did a bit of research and eventually I eventually found a solution which was to create an invisible iframe with a form, then submit the said form to get back the information I require.
However, this form is created in javascript, so I use the form.submit() method to submit the said form, and this, rather than simply giving me the JSON file with the information I require, redirects me to the actual JSON file in a different page altogether.
How can I prevent this from happening?
var ifr = document.createElement('iframe');
var frm = document.createElement('form');
frm.setAttribute("id", "invis_form");
frm.setAttribute("action", endpoint);
frm.setAttribute("method", "post");
var x = document.createElement("INPUT");
x.setAttribute("type", "text");
x.setAttribute("name", "chave");
x.setAttribute("value", apikey);
var y = document.createElement("INPUT");
y.setAttribute("type", "text");
y.setAttribute("name", "valor");
y.setAttribute("value", "125");
frm.appendChild(x);
frm.appendChild(y);
ifr.appendChild(frm);
document.body.appendChild(ifr);
frm.submit();
I was expecting to get something I could print on the console, not to be redirected to a JSON file with the information I need.
The act of submitting a form triggers browser navigation to the response returned from the HTTP request.
The only way to stop it replacing the current page is to make the navigation happen elsewhere (e.g. in a frame or new window) with target … but then cross-origin security would prevent you from reading the data with JavaScript.
You can't use a form to read data from a remote site for the same reasons you can't use Ajax to do it.
The browser is designed to stop your JavaScript from reading data that someone else's website is willing to share with the owner of the browser.
If the data is public (i.e. doesn't need the user to log in, be on the same LAN, or anything similar) then use server-side technology to read it (you can proxy it to the browser).
Figured out you can add https://cors-anywhere.herokuapp.com/ to your endpoint and it will just work, even with Ajax requests.
Example
var apikey = "my-api-key";
var cors = "https://cors-anywhere.herokuapp.com/";
var endpoint = "https://test/example";
$.ajax({
type: "POST",
url: cors + endpoint + "/create",
crossDomain: true,
dataType: 'json',
data: {
'chave': apikey,
'valor': 125.00
},
success: function (data) {
console.log(data);
},
error: function (error) {
console.log(error);
},
});
How or why this works? I have no clue.
I am having an issue with saving a form. The form itself has about 40 rows with around 12 inputs for each row in this style:
On save, it should POST and then close the window. However, it never truly saves it. This makes me think that it is closing the window before it saves. Here's the code in question:
$('#save-btn').click(function() {
document.form.submit();
window.close();
};
If I remove the window.close() and use the inspector than I see in the parameters field that all the values save correctly. This is again what lead me to think that the window is closing to early.
I have tried using the following in the above #save-btn function:
setTimeout('window.close()',5000)
Yet this never seemed to execute the window.close() after the 5 seconds and all around seems like bad programming to force it to wait 5 seconds and then close when it could take any amount of time.
I then attempted to use an AJAX request like:
var _url = 'submit?nameParam="+nameParam+"&com=editlist&'+$('form').serialize();
console.log(_url); //just to see what its pushing out
$.ajax({
url: _url,
error: function(){
alert('Error submitting form.');
},
success: function() {
window.close();
}
});
This resulted in 414 Request-URI Too Long. I know the case for this is it should be a POST to begin with, but I was just trying to make it work.
Just because, this is how our form is set up:
<form name="form" action="submit" method="post">
Our solution was to close the page from our action page
Remove the serialized data from your _url and instead pass it through the .ajax() request with the data setting:
var _url = 'submit?nameParam="+nameParam+"&com=editlist';
$.ajax({
url: _url,
method: "POST",
data: $('form').serialize(),
error: function() {
alert('Error submitting form.');
},
success: function() {
window.close();
}
});
Your ajax approach is correct because you can understand that form submit done correctly with code, on success post it is easy to close the window.
For sending a POST request, you have to make some small changes in your code...
Don't serialize your form and add URL, it is not safe (not working for your situation).
Post your values as "post data".
Here is documentation about it.
https://api.jquery.com/jquery.post/
Please try and update your question if you cannot understand how.
I contacted the tech support about a problem with Ajax where Ajax wouldn't execute due to Access-Control-Allow-Origin problems. He fixed the issue be adding a file called .htaccess containing the code Header set Access-Control-Allow-Origin "*" . I'm saying this because I'm not entirely sure if it's relevant. The issue is that Ajax is switching the value of the Data variable from the input contents to copying the entire script and using that as the value. I have absolutely no idea why this is happening or how but after debugging a bit it seems that this is happening only within Ajax. I checked and JavaScript is correctly taking the value of the input but as it is passed through Ajax the value of the form_data variable is replaced with a copy of the script.
<script type="text/javascript">
$(document).ready(function() {
$("#my_form").submit(function(event){
//alert ("submited");
event.preventDefault("#my_form");
var post_url = $(this).attr("action"); //get form action url
var request_method = $(this).attr("method"); //get form GET/POST method
var form_data = $(this).serialize(); //Encode form elements for submission
//var form_data = $('#submit_post').val(),
alert (post_url + "" + request_method + " " + form_data);
$.ajax({
type: request_method,
url: post_url,
data: form_data,
//crossDomain: true,
success: function( html ) {
alert (html);
$('#server-results').html(html);
},
});
});
});
And here is the screen shot of alert (html);
Thanks
I figured it out guys, the link in the form was the webpage itself! It was originally a second webpage but I changed it to send to itself to see what would happen when I was debugging it and forgot to change it back! For some reason that made ajax output the script of the webpage
i am using ajax to populate a drop down but the call is not going to the server. getting the following error in fire bug
POST 0
status 404 not found
my code is:
function selectChildCategory(parent,child){
var url = "<?php echo url::site('admin/video/showSubCategory/')?>";
if(parent != "")
{
if(child != 0){
url = url+parent+"/"+child;
}else{
url = url+parent+"/"+0;
}
$.ajax({
url: url,
type:"POST",
success: function(select)
{
//alert(select);
$("#sub_category").html(select);
}
});
}
}
the parammeters are showing correct values....but call is not going to the server. The URL is correct
please advise.
404 Error code means that the page your are trying to call does not exists.
You are buildng a HTTP path using your parent and child variables but if the formed url does not exists (or is not captured by any mod_rewrite) a 404 error is shown.
For example, for parent "0" and child "0" the url /admin/video/showSubCategory/0/0 exists?
Also if you are using something like mod_rewrite is really correctly configured?
Try first calling the URL manually to check if the url generated by javascript really exists.
Have you checked that the URL is available via a POST request?
This is my ajax function:
function ajax_call(call_method,data_to_send) {
logger("function ajax_call. var data_to_send: ");
logger(data_to_send);
$('.clickable save_button').hide()
$.ajax({
type: 'POST',
url: call_method,
data: data_to_send,
success: function(data){
logger("data returned to page after ajax call: ");
logger(data);
$('.error_msg').html("Successfully saved record to database.");
$('.error_msg').fadeIn('slow');
setTimeout("$('.error_msg').fadeOut('slow');",5000); // 5 secs to give user enough time to read
$('.clickable save_button').show()
response_dispatcher(data); // This should contain object type at least
},
failure: function(){
$('.error_msg').html("There was an error while saving this information. Please try again. " +
"If the error persists, please contact us using the contact form.");
$('.error_msg').show;
$('.clickable save_button').show()
},
dataType: 'json'
});
}
And, this is the data sent to my method on the backend:
{
'display_order':"3",
'goal':"dummy goal",
'id':-1,
'object_type':"goal"
}
I've verified within my application that this same data is received.
Here is my Django view method:
#login_required
def update_goal_view(request):
if request.method == 'POST' and request.is_ajax:
# Example data sent from AJAX Request
#qd = {u'display_order': [u'23'], u'object_type': [u'goal'], u'goal': [u'dummy goal'], u'id': [u'-1']}
qd = request.POST
goal = qd.get('goal','')
display_order = qd.get('display_order',99999)
id = int(qd.get('id',''))
object_type = qd.get('object_type','')
# For now, just return something to test populating data to the page
id = '100'
goal = 'goal returned'
object_type = object_type
data = {'id':id,'goal':goal,'object_type':object_type}
return HttpResponse(data,mimetype="application/json")
In Firebug, I see this after the ajax call:
POST http://127.0.0.1/xml/update_goal 200 OK 12ms
The issue is, when that it appears that my success callback is never called... I say that because as you can see from above, I there should be a message written to my logger but there isn't one. I know my logger works because of all the other messages outside of the callback that do get written to my logger.
I don't think Django does automatic serialization for dictionaries. You'll have to serialize them to JSON by hand.
import simplejson
# ...
return HttpResponse(simplejson.dumps(data), mimetype="application/json")
You don't show the code that triggers the ajax_call function. If it's as part of the onclick event for a submit button, or the onsubmit event for a form, the usual cause is that you've forgotten to prevent the form from submitting normally - so the page refreshes and the Ajax call is lost.
Use event.preventDefault() in your event handler to fix this.