Before firing AJAX event, manipulate DOM -- CSRF Error - javascript

I'm working with Django, trying to make a chained AJAX call -- that is, a call that, when returned, kicks off more AJAX calls. I've been over the various methods of dealing with CSRF tokens and AJAX that the Django documentation provides, to no avail.
I have working code that allows for this chained AJAX call to successfully go through:
frm.submit(function(e){
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
headers: {'X-CSRFToken':csrftoken},
success: function(data, status){
$('#queue_div').append("<div class='container'>"+data['group_name']+"- "+data['client']+"<div id='queue"+counter+"'></div></div>");
var div_id = 'queue'+counter;
data['div_id'] = div_id;
var token = $.cookie('csrftoken');
data['csrf'] = token;
$('#'+div_id).html(data['status']);
callbackAJAX(data);
} //end success function
}); //end ajax function
e.preventDefault();
But when you delay the form event from firing the AJAX event right away, either by using "beforeSend" (as below):
var data = {'group_name':'name', 'client':'MrClient'}
var counter = 0
frm.submit(function(e){
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
headers: {'X-CSRFToken':csrftoken}
beforeSend:function(e){
$('#foo').append('<div class='container'>"+data['group_name']+"- "+data['client']+"<div id='queue"+counter+"'></div></div>');
} .....
or by adding an event right before the $.ajax call (as below):
frm.submit(function(e){
$('#foo').append('<div class='container'>"+data['group_name']+"- "+data['client']+"<div id='queue"+counter+"'></div></div>');
$.ajax({
type: frm.attr('method')....
You get a CSRF error.
I was successful in doing very, very simple functions such as the following:
var counter = 0;
frm.submit(function(e){
$.ajax({
type: frm.attr('method'),
sendBefore: function(e){
counter++;
}
But that's it. Anything more complicated gets rejected. I'm thoroughly confused as how to make heads or tails of what is actually happening OR what is acceptable to Django. & its CSRF protection.

The HTML you are trying to append is invalid. I believe that's why the form submission is not working. First you are trying to insert an element with ID foo into an element with the same ID ( foo ). Which is invalid HTML since IDs should never be repeated within the page.
Second and main problem is that you are appending <div id=foo></div> which should be <div id="foo"></div>

Related

Reload url in javascript with ajax

I'm trying to refresh an affiliate URL which is inside a piece of JavaScript with AJAX, but I can't get it to work.
Here's the code:
<script type="text/javascript">
(function() {
var mdWidgetUrl = "https://herecomestheurl";
var s = document.createElement("script"),
s1 = document.getElementsByTagName("script")[0];
s.type = "text/javascript";
s.async = true;
s.src = mdWidgetUrl;
s1.parentNode.insertBefore(s, s1);
})();
function fetchdata(){
$.ajax({
url: 's.src',
type: 'post',
success: function(data){
// Perform operation on return value
alert(data);
},
complete:function(data){
setTimeout(fetchdata,10000);
}
});
}
$(document).ready(function(){
setTimeout(fetchdata,10000);
});
</script>
What I'm trying to do is to AJAX reload the URL, which is known as "mdWidgetUrl", every 10 seconds without refreshing the whole page. This code doesn't work, because I don't know how to tag the s.src within the AJAX function.
Let's have a look to the different settings of your AJAX call:
url:
When you try:
url: 's.src',
you are not passing the content of the src property of the s object; you are literally passing the string "s.src". But even if you do:
url: s.src,
it won't work because s is out of scope. s was declared inside an IIFE ( (function() {... ) and it lives just inside it. You can not access it from outside.
Instead, after you create your s script, you can give it an id. Like this:
var s = document.createElement("script");
s.id = "mdWidgetScript";
Then, you can easily retrieve the value of the src attribute from the ajax call:
$.ajax({
url: $("#mdWidgetScript").attr('src'),
Note that using an id is not mandatory. You could find the script like you found s1, selecting the first element with a <script> tag:
url: document.getElementsByTagName("script")[0].getAttribute("src");
// or with jQuery
url: $("script:eq(0)").attr('src');
I just find using an id a cleaner and more bulletproof way.
type:
It is an alias for method. You are retrieving data from the server, not sending to. Switch POST to GET (or leave this setting out, since GET is the default). Read this question about the differences.
dataType:
You should set the dataType accordingly (check this question). If the URL points to a script, use dataType: "script",. Actually, you could use $.getScript() which is a shorthand method for this kind of AJAX call.
If after properly tuning your settings you still have troubles:
Check for errors in the console.
Ensure the data being send is well-formed
Read this other questions:
Why does jQuery insist my plain text is not “well-formed”?
jQuery.ajax success callback function not executed

Trigger function on a global $.ajax event for a specific ajax call

I've got 3-4 ajax calls that will be made at some point.
For one of those calls I'd like to trigger a function on the ajaxSend event which is global. This specific ajax call is not necesserily the first or last one in the sequence. It seems that if I attach the ajaxSend event to the $(document), my function will fire every other time that an ajaxSend event occurs. Here's what my code looks like:
//ajax call one
$.ajax({
type: "POST",
url: myUrl,
data: myData
});
//ajax call two <- let's say I'd like to fire ajaxSpecificFunc() here
$.ajax({
type: "POST",
url: myUrl,
data: myData
});
//ajax call three
$.ajax({
type: "POST",
url: myUrl,
data: myData
});
function ajaxSpecificFunc(){
$(document).on("ajaxSend", function() {
//Some code that should only happen on ajaxSend but for only one ajax call
});
}
EDIT: I am aware of global:false property for ajax, but do not wish to use it, as this would mean I would have to modify every new ajax call in the future to have ajaxSpecificFunc() continue to fire for the one specific ajax call
You can add beforeSend in jQuery.ajax():
$.ajax({
type: "POST",
url: myUrl,
data: myData,
beforeSend: ajaxSpecificFunc
});
As noted by A.Wolff, this way if we call this function it will bind the ajaxsend for each call. Instead you can remove it and just do the specific ones like:
function ajaxSpecificFunc(jqXHR, settings){
// you can work with the jqXhr and settings
}
If you can't bind the handler directly to the ajax call, and want to use the global handlers only then you can check the setting object to see whether the ajax call is your targeted on and if so then call your stuff
$(document).ajaxSend(function(event, jqXHR, settings) {
console.log('send', settings);
if (settings.url == 'myurl') {
//then do your stuff
}
})
Note: But this might become an overkill, and you should try to do it specific to your ajax call

Why is my jquery ajax not working on my page and page is also refreshing

I am new in the area of jQuery/Ajax and my little test function doesn't work. And my page is also refreshingcan any one help me
<script type="text/javascript" >
$(document).ready(function() {
$("#ser_itm").change(function() {
var id=$(this).val();
var dataString = 'id='+ id;
alert(dataString);
$.ajax({
type: "POST",
url: "bar_pull.php",
data: dataString,
cache: false,
success: function(html) {
$("#tbl").html(html);
}
});
});
});
Pass the function, not the result of the function call:
$('.linkDetails').on('click', getDetailsFromServer);
Apply the same to your AJAX success callback:
success: postToPage
Also, the getDetailsFromServer() function needs to be defined before you bind it to an event. Move the function declaration before your .on('click', ...) call.
So I'm going to try and explain these points more clearly:
You cannot access C:\Users\yah\Desktop\text.txt. This is a server side path, your javascript runs on the client side. So this needs to be a path you can browse to in your browser, something like /pathinURL/text.txt. How you do this is dependant on your hosting technology, etc.
Your call backs are also wrong,
$('.linkDetails').on('click', getDetailsFromServer());
&
success: postToPage()
these will execute the function when they are hit, (well it actually binds the function result) not when the event happens. To make these work you need to remove the braces:
$('.linkDetails').on('click', getDetailsFromServer);
&
success: postToPage
this then hooks up the actual functions as function pointers and thus the actual functions will be fired when you want them to be.
so your final code will look like:
$('.linkDetails').on('click', getDetailsFromServer);
function getDetailsFromServer() {
$.ajax({
type: 'GET',
url: '/someURL/text.txt',
success: postToPage
});
}
function postToPage(data) {
$('.textDetails').text(data);
console.log(data);
}
what Arun P Johny said is right! but your code has another probloem
$('.linkDetails').on('click', getDetailsFromServer);
try above
The same origin policy implemented by browsers prevents local file system urls... if the page and the files are in same folders it might work.
See SOP for file URI for FF

Can ajax call on return add new javascript function to the page?

I have a jQuery ajax call that returns html of a table. Now I need to let user to do some javascript action on the table.
Can the return ajax response contain the javascript code or do I have to load the javascript code in the page on the first load of the page?
The user has the option of triggering the 'new' javascript. It doesn't have to triggered on ajax call.
To answer the actual question, the return response can contain the script. Simplest is to place it after the html, as the ready event has already fired in page it is being loaded into
You can use the success (or other event) callbacks provided with jQuery .ajax() to perform this JS action. Something like this:
$.ajax({
success: function(){
// Perform JS action
}
}
The jQuery API lists all such event callbacks available for AJAX calls. Check this for more info.
The returned ajax response can contain javascript code as a string. Then you can eval(response).
If you want to request a script with ajax that will be run when retrieved, then you can use jQuery's getScript() method to retrieve it and then execute it.
Per the jQuery doc, getScript() is a shorthand for:
$.ajax({
url: url,
dataType: "script",
success: success
});
Which shows that jQuery's ajax command will handle a returned script for you automatically if you set the data type appropriately.
You can make your request a variable and extend upon it after the set up.
// Make the request to the server
var dataID = $("#WhatINeedForAParameter").val();
var request = $.ajax({
url: "PageOrControllerOrWebApi/MethodName",
type: "POST",
data: { id : dataID },
dataType: "json"
});
// When the request is done process
// what you need done
request.done(function(msg) {
alert('You got this ' + msg);
});
// If the request failed you can
// see what the problem was and
// handle the situation accordingly
request.fail(function(jqXHR, textStatus) {
alert( "Your request failed: " + textStatus );
});
you can do it using success callback i think this can be a way please try
$.ajax({
.....,
.....,
success:
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
$("#tableID").append( script );
});
i hope it should help.

maintain function order in jQuery ajax callback function

I have a jQuery ajax function. the callback function consists of two functions:
1) Take the ajax result (which is an html form) and insert it as an html span's inner html.
2) Submit this form
How can I ensure that the form is loaded before JavaScript tries to submit it?
Code:
$("select").live("change", function(){
FormUpdate();
})
function FormUpdate() {
$.ajax({
type: "POST",
url: "index.php?UpdateForm=Yes",
data: $("#Form").serialize(),
success: function(msg){
$("span#Content").html(msg);
$("#Form").submit();
}
});
}
My problem comes because javascript tries to submit the form before it has loaded and my data submitted.
Just simply put the function for taking ajax result and insert into the DOM in front and the form submission function at the back.
Only after insertion is done, the next function will be called.
Example:
$.ajax({
type: "POST",
url: "backend.php",
data: "name=John",
dataType: "json"
success: function(msg){
$("#thediv").html(msg.html);
$("form#theform").submit();
}
});
DOM manipulations are synchronous so the form wont be submitted until afterwards. Are you having a specific problem with this scenario? Please post tons of code, if so :)

Categories

Resources