I tried to implement codeigniter with $config['csrf_regenerate'] = TRUE;
I create code with combining javascript XMLHttpRequest & Jquery $.ajaxPrefilter.
I make a function for getting new csrf_hash from Codeigniter and append to meta name on HTML head.
At first request everything seems working.
But next request a got message 403 Forbidden because ajax send an old csrf hash.
Please fix my code.
I want before sending a POST request, ajax get new csrf hash form meta name on HTML head.
Sorry for my bad English.
Best Regards,
This is my code
$.ajaxPrefilter(function( options, originalOptions, jqXHR )
{
get_csrf_hash(callback => document.querySelector('meta[name="csrf_hash"]').setAttribute("content", callback) ); // It Work!!.. Get new csrf_hash and update content meta name.
if (options.type.toLowerCase() === "post")
{
options.data = $.param($.extend(originalOptions.data, { csrf_simpeg_v2 : document.querySelector('meta[name="csrf_hash"]').getAttribute("content")})); // Not Work didn't send fresh csrf hash
}
var originalSuccess = options.success;
options.success = function(data)
{
if (originalSuccess != null)
{
originalSuccess(data);
}
}
var originalError = options.error;
options.error = function (jqXHR, textStatus, errorThrown)
{
console.log(jqXHR.status + ' ' + jqXHR.statusText);
if(jqXHR.status == 401 || jqXHR.status == 403)
{
alert(jqXHR.status + ' ' + jqXHR.statusText);
}
else
{
if(originalError != null)
{
originalError();
}
}
};
});
function get_csrf_hash(callback)
{
var url = baseURL + 'login/get_csrf_token';
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function()
{
if (xhr.readyState == XMLHttpRequest.DONE)
{
console.log(xhr.responseText);
return callback(xhr.responseText);
}
}
xhr.open('GET', url, true);
xhr.send(null);
}
$(function () {
});
get_csrf_hash is an asynchronous function, meaning that the JavaScript runtime will not wait for it to finish its task before moving on to executing the next lines. You need to put all the code that depends on the first AJAX request inside the callback:
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
get_csrf_hash(callback => {
document.querySelector('meta[name="csrf_hash"]').setAttribute('content', callback);
if (options.type.toLowerCase() === 'post') {
options.data = $.param(
$.extend(originalOptions.data, {
csrf_simpeg_v2: document.querySelector('meta[name="csrf_hash"]').getAttribute('content')
})
);
}
var originalSuccess = options.success;
options.success = function(data) {
if (originalSuccess != null) {
originalSuccess(data);
}
};
var originalError = options.error;
options.error = function(jqXHR, textStatus, errorThrown) {
console.log(jqXHR.status + ' ' + jqXHR.statusText);
if (jqXHR.status == 401 || jqXHR.status == 403) {
alert(jqXHR.status + ' ' + jqXHR.statusText);
} else {
if (originalError != null) {
originalError();
}
}
};
});
});
You should look into the Fetch API and Promises. They will greatly simplify writing code like this. Here is the get_csrf_hash re-written using those tools:
function get_csrf_hash(callback) {
fetch('login/get_csrf_token')
.then(res => res.text())
.then(text => callback(text));
}
Related
I have this function to execute Ajax POST request :
function ajaxPost(url, data, callback) {
var req = new XMLHttpRequest();
req.open("POST", url, true);
req.addEventListener("load", function () {
if (req.status >= 200 && req.status < 400) {
callback(req.responseText);
} else {
console.error(req.status + " " + req.statusText + " " + url);
}
});
req.addEventListener("error", function () {
console.error("Erreur réseau avec l'URL " + url);
});
req.send(data);
}
But with this code, the captcah is never checked :
grecaptcha.ready(function() {
grecaptcha.execute('reCAPTCHA_site_key', {action: 'homepage'}).then(function(token) {
var data = new FormData();
data.set('g-recaptcha-response',token);
ajaxPost("url", data, function(response){
return response;
});
});
});
The script execute ajaxPost() BEFORE grecaptcha.execute().
Thank you for your help !
I'm not sure what you need the callback for? You're already assigning a listener to "load". I think you can directly return req.responseText in that listener.
Just a guess..
Like the title says: "Uncaught ReferenceError: make_basic_auth is not defined"
I have a sensor that is connected to the app via bluethooth. The app sends the data to the cloud service. I got a link from the cloud service that contains the data in a json format and I have to GET the data from it.
make_basic_auth is a function to authentificate my GET request.
Im new and I dont have a clue what I did wrong.
<html>
<head>
<title>Test</title>
<script src="jquery-3.2.1.min.js"></script>
<script src="Base64Toolkit.js"></script>
</head>
<body>
<button onclick="myFunctionPost()">Post</button>
<div id="result" style="color:red"></div>
<script>
function make_base_auth(user, password) {
var tok = user + ':' + pass;
var hash = Base64.encode(tok);
return "Basic " + hash;
}
var auth = make_basic_auth('myUSERNAME','myPASSWORD');
var url = 'myURL';
// RAW
xml = new XMLHttpRequest();
xml.setRequestHeader('Authorization', auth);
xml.open('GET',url)
// ExtJS
Ext.Ajax.request({
url : url,
method : 'GET',
headers : { Authorization : auth }
});
// jQuery
$.ajax({
url : url,
method : 'GET',
beforeSend : function(req) {
req.setRequestHeader('Authorization', auth);
}
});
function myFunctionPost() {
var getJSON = function(url) {
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.responseType = 'json';
xhr.onload = function() {
var status = xhr.status;
if (status == 200) {
resolve(xhr.response);
} else {
reject(status);
}
};
xhr.withCredentials = true;
xhr.send();
});
};
getJSON('myURL').then(function(data) {
alert('Your Json result is: ' + data.result); //you can comment this, i used it to debug
result.innerText = data.result; //display the result in an HTML element
}, function(status) { //error detection....
alert('Something went wrong.');
});
}
</script>
</body>
</html>
Typo:
make_base_auth <- defined
make_basic_auth <- used
I'm trying to call a view in Elgg via AJAX, but nothing works after >>HERE<<
$('.glyphicon-zoom-in').click(function(event) {
$( '.full-image-view' ).css( "color", "red" ).append('<div>Hope this works</div>');
// >>HERE<<
var Ajax = require('elgg/Ajax');
var ajax = new Ajax();
ajax.view('albums/inline_full_image_view', {
data: {
guid: 123 // querystring
},
}).done(function (output, statusText, jqXHR) {
if (jqXHR.AjaxData.status == -1) {
return;
}
$('.full-image-view').append(output);
});
});
Output : Hope this works
What could I be getting wrong?
Thank you all in advance.
UPDATE
inline_full_image_view.php
<?php
echo 'Hello World';
Elgg uses requirejs. Try this:
requirejs(["elgg/Ajax"], function(Ajax) {
var ajax = new Ajax();
//rest of your code!!
});
Otherwise, using native JS.
var xhr = new XMLHttpRequest();
xhr.open('GET', encodeURI('albums/inline_full_image_view'));
xhr.onload = function() {
if (xhr.status === 200) {
alert('User\'s name is ' + xhr.responseText);
}
else {
alert('Request failed. Returned status of ' + xhr.status);
}
};
xhr.send();
I've been trying to get an ajax alert layer to work with a POST method for several days and I can't come up with a reason for it not working. I use the same basic code to send form data through ajax with POST on other admin pages without trouble but when I try to send data that does not come from a form nothing gets to the server in $_POST.
Here's the flow of the code...
I use variables on a page like these:
$alertLayer = 1;
$autoCloseAlertLayer = 1;
$addAlertLayerCloseButton = 1;
$alertLayerMessage = $alertLayerMessage . '<h1>Test</h1><p>3rd test of the alert layer module.</p>';
$redirect = 0;
$redirectTo = 0;
and I include a script that calls a function at the bottom of the page like this:
if ($alertLayer == true)
{
echo "<script type='text/javascript' id='alertLayerScript'>Lib.ajaxAlertFunction('/Modules/AlertLayer', $autoCloseAlertLayer, $addAlertLayerCloseButton, '$alertLayerMessage', $redirect, '$redirectTo');</script>";
}
Here's the script that gets called:
Lib.ajaxAlertFunction = function (senturl, autoClose, closeButton, message, redirect, redirectTo)
{
var ajaxRequest;
try
{
ajaxRequest = new XMLHttpRequest();
}
catch (e)
{
try
{
ajaxRequest = new ActiveXObjext("Msxml2.XMLHTTP");
}
catch (e)
{
try
{
ajaxRequest = new ActiveXObjext("Microsoft.XMLHTTP");
}
catch (e)
{
alert ("Your browser can't handle the truth!");
return false;
}
}
}
if (!senturl)
{
return false;
}
else
{
// var data = "autoClose=" + encodeURIComponent(autoClose) + "&closeButton=" + encodeURIComponent(closeButton) + "&message=" + encodeURIComponent(message) + "&redirect=" + encodeURIComponent(redirect) + "&redirectTo=" + encodeURIComponent(redirectTo);
// var data = encodeURIComponent("autoClose=" + autoClose + "&closeButton=" + closeButton + "&message=" + message + "&redirect=" + redirect + "&redirectTo=" + redirectTo);
var data = "autoClose=" + autoClose + "&closeButton=" + closeButton + "&message=" + message + "&redirect=" + redirect + "&redirectTo=" + redirectTo;
}
ajaxRequest.onreadystatechange = function()
{
if (ajaxRequest.readyState == 4 && ajaxRequest.status == 200)
{
document.getElementById('outerFrame').innerHTML += ajaxRequest.responseText;
newAlertLayer = document.getElementById('alertLayer');
var arr = newAlertLayer.getElementsByTagName('script')
for (var n = 0; n < arr.length; n++)
{
eval(arr[n].innerHTML)
}
}
}
ajaxRequest.open('POST', senturl, true);
ajaxRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
ajaxRequest.send(data);
}
NOTE: I have no problem sending this data with a 'GET' method but then a long message gets cut off. I have also tried to set up the 'data' variable in several different methods that I've searched over the past 3 days with no success.
The code that expects $_POST data goes as follows:
<?php
$ROOT = $_SERVER['DOCUMENT_ROOT'];
?>
<div id="alertLayer">
<link rel="stylesheet" href="<?php $ROOT ?>/Modules/AlertLayer/alertLayer.css">
<script src="/Modules/AlertLayer/alertLayer.js"></script>
<div id="alertBlock">
<?php
foreach ($_POST as $key => $value)
{
echo "<p>" . $key . " = " . $value . "</p>";
}
foreach ($_GET as $key => $value)
{
echo "<p>" . $key . " = " . $value . "</p>";
}
?>
</div>
</div>
What am I missing? What is different from sending form data with POST and sending variables concatenated the same way?
Again, GET is working when I add the data to the url string but not sufficient, POST = no data at all received on the other end of the ajaxRequest but the rest of the request returns exactly what is expected. The $_POST data missing from the server request is currently the only problem that I cannot solve with this code.
It's looking like the request is not being sent properly but I'm unable to determine the reason. Here's a screenshot of what NETWORK tab in chrome:
Problem was a redirection (301) issued by nginx due to a missing slash at the end of the URL. This caused the POST request to be changed to GET.
Technical Details: https://softwareengineering.stackexchange.com/questions/99894/why-doesnt-http-have-post-redirect
Old approach that started the discussion:
Your Problem seems to be the encodeURIComponent() function that you're wrapping around the whole data string. This replaces the & signs with & values. If you debug this in the browsers developer console you'll see that it is not recognized as form data in the request. You should only escape the variables you're filling in.
Btw: This should also be problematic when you use GET.
This is more or less what I tried and it was sending data via POST.
window.onload=function(){
Lib.ajaxAlertFunction( '/test/target.php', 0, 0, 'Fantastic - data is being sent via POST! Amazeballs!', 0, 0 );
};
var Lib={}; /* Because I don't have the rest of `Lib` at my disposal */
Lib.ajaxAlertFunction = function ( senturl, autoClose, closeButton, message, redirect, redirectTo ) {
var ajax;/* renamed only for brevity */
try {
ajax = new XMLHttpRequest();
} catch (e) {
try {
ajax = new ActiveXObjext("Msxml2.XMLHTTP");
} catch (e) {
try {
ajax = new ActiveXObjext("Microsoft.XMLHTTP");
} catch (e) {
alert ("Your browser can't handle the truth!");
return false;
}
}
}
if ( !senturl ) return false;
else {
var data = "autoClose=" + autoClose + "&closeButton=" + closeButton + "&message=" + message + "&redirect=" + redirect + "&redirectTo=" + redirectTo;
}
ajax.onreadystatechange = function() {
if( ajax.readyState == 4 && ajax.status == 200 ) {
/*
document.getElementById('outerFrame').innerHTML += ajax.responseText;
newAlertLayer = document.getElementById('alertLayer');
var arr = newAlertLayer.getElementsByTagName('script')
for ( var n = 0; n < arr.length; n++ ) {
eval( arr[n].innerHTML );
}
*/
console.log( ajax.responseText );
}
}
ajax.open( 'POST', senturl, true );
ajax.setRequestHeader( 'Content-Type', 'application/x-www-form-urlencoded' );
ajax.send( data );
}
For the sake of the test, /test/target.php was simply:
<?php
exit( print_r($_POST,true) );
?>
and the response:
Array
(
[autoClose] => 0
[closeButton] => 0
[message] => Fantastic - data is being sent via POST! Amazeballs!
[redirect] => 0
[redirectTo] => 0
)
If it helps any, here is a basic ajax function I use in tests, perhaps something in there might be of use?
function _ajax( url, options ){
var factories=[
function() { return new XMLHttpRequest(); },
function() { return new ActiveXObject('Msxml2.XMLHTTP'); },
function() { return new ActiveXObject('MSXML2.XMLHTTP.3.0'); },
function() { return new ActiveXObject('MSXML2.XMLHTTP.4.0'); },
function() { return new ActiveXObject('MSXML2.XMLHTTP.5.0'); },
function() { return new ActiveXObject('MSXML2.XMLHTTP.6.0'); },
function() { return new ActiveXObject('Microsoft.XMLHTTP'); }
];
/* Try each factory until we have a winner */
for( var i=0; i < factories.length; i++ ) {
try { var req = factories[ i ](); if( req!=null ) { break; } }
catch( err ) { continue; }
};
var method=options.hasOwnProperty('method') ? options.method.toUpperCase() : 'POST';
var callback=options.hasOwnProperty('callback') ? options.callback :false;
if( !callback ){
alert( 'No callback function assigned - a callback is required to handle the response data' );
return false;
}
var headers={
'Accept': "text/html, application/xml, application/json, text/javascript, "+"*"+"/"+"*"+"; charset=utf-8",
'Content-type': 'application/x-www-form-urlencoded',
'X-Requested-With': 'XMLHttpRequest'
};
/* The main parameters of the request */
var params=[];
if( options.hasOwnProperty('params') && typeof( options.params )=='object' ){
for( var n in options.params ) params.push( n + '=' + options.params[n] );
}
/* Additional arguments that can be passed to the callback function */
var args=options.hasOwnProperty('args') ? options.args : options;
/* Assign callback to handle response */
req.onreadystatechange=function(){
if( req.readyState==4 ) {
if( req.status==200 ) options.callback.call( this, req.response, args );
else console.warn( 'Error: '+req.status+' status code returned' );
}
}
/* Execute the request according to desired method */
switch( method ){
case 'POST':
req.open( method, url, true );
for( header in headers ) req.setRequestHeader( header, headers[ header ] );
req.send( params.join('&') );
break;
case 'GET':
req.open( method, url+'?'+params.join('&'), true );
for( header in headers ) req.setRequestHeader( header, headers[ header ] );
req.send( null );
break;
}
}
/* to use */
_ajax.call( this, '/test/target.php',{ callback:console.info, method:'post',params:{'field':'value','field2':'value2'} } );
When calling the ajaxRequest the url MUST have a "/" at the end of the url (if you're not specifying an /index.php file for example).
I was using '/Modules/AlertLayer' and changing to '/Modules/AlertLayer/' has fixed the problem!
I have this code-behind:
[WebMethod]
[ScriptMethod(UseHttpGet=true)]
public string GetMessage() {
XmlTextReader reader = new XmlTextReader (Global.sAppPath + "/alt/importantMsg.xml");
string message = null;
while (reader.Read()) {
if (reader.IsStartElement ()) {
switch (reader.Name.ToString ()) {
case "Message":
message = reader.ReadString();
break;
}
}
}
return message;
}
And I want to retrieve the message (the string that the code-behind returns) using jQuery. So I have this code:
$(document).ready(function () {
$.get("isoServe.asmx/GetMessage", function(data, status) {
alert("Data: " + data + "\nStatus: " + status);
});
});
But this is not working for me. It's like I can't get a hole through. What am I doing wrong?
I also tried this:
$(document).ready(function () {
$.ajax({
url: "isoServe.asmx/GetMessage",
data: "message",
dataType: "json",
success: function (data) {
alert(data);
}
});
});
But this last piece of code, I am very unsure about. How should the "data" be given in this one.
The example below, does work (using xmlhttp). But I want to use jQuery
function getMsg() {
var msg = "";
xmlhttp = gus.tie = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
msg = xmlhttp.responseXML.documentElement.textContent;
alert("Msg: " + msg + ": fra getMsg()");
}
};
xmlhttp.open("GET", "isoServe.asmx/GetMessage", false);
xmlhttp.send();
return msg;
}
Sorry folks, for some reason the referenced file from the url had been deleted. That's why it wouldn't find it. I have a lot of debugging to do it seems, omg. Wish me luck.
Thanks for your time