So, I've been working on a project that citizens can report problems on public places for the municipal government by filling a little form after selecting the place on Google Maps.
We need to implement reCAPTCHA for validation and stop/slow people from spamming our servers.
The data inputted in the form is sent through AJAX to an API that redirects it to add-problem.php but when I add 'g-recaptcha-response' and recaptcha.getResponse(); on my formData, the code stops working.
var formData = new FormData();
formData.append("description", description);
formData.append("pic", picture[0]);
formData.append("cpf", cpf);
formData.append("status", 1);
formData.append("keyword", keyword);
formData.append("type", "add-problem");
formData.append("place_id", $("#name").attr('data-id'));
formData.append("g-recaptcha-response", recaptcha.getResponse());
$.ajax({
type: 'POST',
url: '../../back/api/api.php',
data: formData,
cache: false,
contentType: false,
processData: false,
beforeSend: function () {
$("#loader").show();
},
success: function (data) {
$("#loader").hide();
console.log("success");
data = JSON.parse(data);
if (data.error) {
swal('Error', data.msg, 'error');
} else {
swal({
title: 'Sucess',
text: data.msg,
type: 'success',
onClose: () => {
location.reload();
}
The error on my console log is
Uncaught SyntaxError: Unexpected token O in JSON at position 0
at JSON.parse (<anonymous>)
at Object.success (municipe.php:467)
at u (jquery-3.3.1.min.js:2)
at Object.fireWith [as resolveWith] (jquery-3.3.1.min.js:2)
at k (jquery-3.3.1.min.js:2)
at XMLHttpRequest.<anonymous> (jquery-3.3.1.min.js:2)
I also tried to send the code statically creating a var and attributing the secret key into it, but I had the exact same error. What could it be?
EDIT: So... I realized what was the problem. Basically, I was sending a var called "g-recaptcha-response" throught the AJAX but my PHP was trying to receive one named as "recaptcha-response". That fixed the problem with my SweetAlert Modal!
Related
I'm trying to figure out what is Adobe Coldfusion and how to work on this platform.
I'm stuck at simple issue.
On submit I send form with jQuery ajax to server.
But I got response: 500 (Element MY_VAR is undefined in FORM.)
What I'm doing wrong?
JS
$loginForm.on('submit', function(e) {
e.preventDefault();
var formData = new FormData(e.target);
$.ajax({
url: 'test.cfm',
method: 'POST',
cache: false,
processData: false,
data: formData,
error: function(err) {
console.log(err);
},
success: function(data, status) {
console.log(status);
console.log(data);
}
});
});
CF
<cfoutput>
<p>#form.myvar#</p>
</cfoutput>
500 indicates an internal server error.
Are you trying to display your form values after sending them?
Maybe try and use the cfdump tag. Very useful for debugging.
Try dumping the form scope and see what variables are actually in there.
Lately I've been trying to solve an issue with no luck, basically I'm trying to submit a form to the server using AJAX, the form has files, so I'm using the FormData javascript object in JQuery 1.12. The data arrives to the server but in I way I don't know how to format it.
This is my AJAX function:
function saveMenu(id){
var formElement = document.getElementById("menu-form");
var formData = new FormData(formElement);
formData.append('_method', 'PUT');
$( "#form-wrapper" ).toggleClass( "be-loading-active" );
$.ajax({
type: 'PUT',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: "{{url('myUrl')}}",
data: formData,
enctype: 'multipart/form-data',
processData: false,
success: function(response) {
toastr.success('Yai! Saved successfully!')
},
error: function(response) {
toastr.error('Oh oh! Something went really wrong!')
},
complete: function() {
$( "#form-wrapper" ).toggleClass( "be-loading-active" )
}
});
}
and when I perform a dd($request->all()); in my controller I get something like this:
array:1 [
"------WebKitFormBoundaryRCIAg1VylATQGx46\r\nContent-Disposition:_form-data;_name" => """
"_token"\r\n
\r\n
jtv4bnn8WQnP3eqmKZV3xWka2YOpnNc1pgrIfk0D\r\n
------WebKitFormBoundaryRCIAg1VylATQGx46\r\n
Content-Disposition: form-data; name="blocks[43][title]"\r\n
\r\n
...
Things I've tried:
Set the HTTP verb to POST. Same result.
Set the AJAX contentType: false, contentType: application/json. Empty response.
Remove enctype: 'multipart/form-data'. Same response.
Any help is appreciated.
This fixed it for me
data: form_data,
contentType: false,
processData: false,
processData: false prevents jQuery from parsing the data and throwing an Illegal Invocation error. JQuery does this when it encounters a file in the form and can not convert it to string (serialize it).
contentType: false prevents ajax sending the content type header. The content type header make Laravel handel the FormData Object as some serialized string.
setting both to false made it work for me.
I hope this helps.
$('#my-form').submit(function(e) {
e.preventDefault();
var api_token = $('meta[name="api-token"]').attr('content');
form_data = new FormData(this);
$.ajax({
type: 'POST',
url: '/api/v1/item/add',
headers: {
Authorization: 'Bearer ' + api_token
},
data: form_data,
contentType: false,
processData: false,
success: function(result,status,xhr) {
console.log(result);
},
error: function(xhr, status, error) {
console.log(xhr.responseText);
}
});
});
also remember to use $request->all(); $request->input() excludes the files
I've been trying to debug that for 2 hours and i found out that method PUT is not working with formData properly.
Try changing
type : "PUT"
into
method : "POST"
Then change your method on your backend from put to post and you'll see the difference.
I used below codes to test it
$("#menu-form").submit(function (){
var fd = new FormData();
fd.append('section', 'general');
fd.append('action', 'previewImg');
fd.append('new_image', $('.new_image')[0].files[0]);
$.ajax({
method : 'POST',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token()}}'
},
url: "{{url('upload-now')}}",
data : fd,
contentType: false,
processData: false,
success: function(response) {
console.log(response);
},
});
return false;
});
And in my controller
public function test(Request $request){
dd($request->all());
}
Ill try to research more about this issue.
Laravel 7,
if use method PUT in ajax, you can follow
1. change method method: 'PUT' to method: 'POST'
2. add formdata.append with _method PUT like this example :
$('#updateBtn').click(function(e){
e.preventDefault();
var frm = $('#tambahForm');
frm.trigger("reset");
$('.edit_errorNama_kategori').hide();
$('.edit_errorGambar').hide();
var url = "/pengurus/category/"+$('#edit_id').val();
var formdata = new FormData($("#editForm")[0]);
formdata.append('_method', 'PUT'); //*** here
$.ajax({
method :'POST', //*** here
url : url,
data : formdata,
dataType : 'json',
processData: false,
contentType: false,
success:function(data){
if (data.errors) {
if (data.errors.nama_kategori) {
$('.edit_errorNama_kategori').show();
$('.edit_errorNama_kategori').text(data.errors.nama_kategori);
}
if (data.errors.gambar){
$('.edit_errorGambar').show();
$('.edit_errorGambar').text(data.errors.gambar);
}
}else {
frm.trigger('reset');
$('#editModal').modal('hide');
swal('Success!','Data Updated Successfully','success');
table.ajax.reload(null,false);
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Please Reload to read Ajax');
console.log("ERROR : ", e);
}
});
});
its works for me
Finally I gave up trying to make it work and tried a more vanilla approach, I still don't know the reason why the request is formated like that, but the XMLHttpRequest() function works perfectly and the migration is not a big deal.
The equivalent of the function I posted about would be:
function saveMenu(action){
var formElement = document.getElementById("menu-form");
var formData = new FormData(formElement);
formData.append('_token', $('meta[name="csrf-token"]').attr('content'));
var request = new XMLHttpRequest();
request.open("POST", "{{url('myUrl')}}");
request.send(formData);
request.onload = function(oEvent) {
if (request.status == 200) {
toastr.success('Yai! Saved successfully!');
} else {
toastr.error('Oh oh! Something went really wrong!');
}
$( "#form-wrapper" ).toggleClass( "be-loading-active" );
};
}
Bit late, but;
This will solve your problem;
var formData = new FormData(document.getElementById('form'));
console.log(...formData);
var object = {};
formData.forEach(function (value, key) {
object[key] = value;
});
Then you can send this object to the server. This is much more readable and works great.
OR
You can simply send this directly;
JSON.stringify(Object.fromEntries(formData));
This is the newer approach.
And don't give up :-)
I have implemented infinite scroll that appends html in the exact same manner as the static item with forms (inclusive csrf), but the dynamic forms that has been appended seems to be submitting without ajax and failing when pressing the submit button.
I get this error on the appended forms in console log:
Resource interpreted as Document but transferred with MIME type application/json:
The ajax submit.
$('.cart_add').on('submit',function (event) {
$.ajax({
type: 'POST',
url: url,
data: data,
beforeSend: function (request) {
return request.setRequestHeader('X-CSRF-Token', $("meta[name='csrf-token']").attr('content'));
},
success: function (data) {
console.log("item has been added to cart");
event.preventDefault();
}
});
});
Edit I noticed that the jquery doesn't select the dynamically appended forms
Try setting your content type. The content type is the type of data sent to the server. In this case, you are sending data to the server which is interpreted as a Document (html) but is sent as json. This is because the browser is trying to infer what type of data your are sending becuase you did not explicitly state it.
Use the contentType to set it.
contentType: "text/html"
So your call should look like this:
$.ajax({
type: 'POST',
url: url,
data: data,
contentType: "text/html",
beforeSend: function (request) {
return request.setRequestHeader('X-CSRF-Token', $("meta[name='csrf-token']").attr('content'));
},
success: function (data) {
console.log("item has been added to cart");
event.preventDefault();
}
});
Aim - to get the twitter followers of a particular user using javascript
I have tried the below code as a POC-
$(document).ready(function() {
// Handler for .ready() called.
$.ajax({
url: "https://api.twitter.com/1.1/followers/ids.json?callback=?",
type: "GET",
data: { cursor: "-1",
screen_name: "twitterapi" },
cache: false,
dataType: 'json',
success: function(data) { alert('hello!'); console.log(data);},
error: function(html) { alert(html); },
beforeSend: setHeader
});
function setHeader(xhr) {
if(xhr && xhr.overrideMimeType) {
xhr.overrideMimeType("application/j-son;charset=UTF-8");
}
//var nonce = freshNonce();
//var timestamp = freshTimestamp();
//var signature = sign(nonce,timestamp);
//alert(signature);
//alert(accessToken+"-"+consumerKey);
//alert(oauth_version+"-"+oauth_signature_method);
xhr.setRequestHeader('Authorization','OAuth');
xhr.setRequestHeader('oauth_consumer_key', 'HdFdA3C3pzTBzbHvPMPw');
xhr.setRequestHeader('oauth_nonce', '4148fa6e3dca3c3d22a8315dfb4ea5bb');
xhr.setRequestHeader('oauth_signature','uDZP2scUz6FUKwFie4FtCtJfdNE%3D');
xhr.setRequestHeader('oauth_signature_method', 'HMAC-SHA1');
xhr.setRequestHeader('oauth_timestamp', '1359955650');
xhr.setRequestHeader('oauth_token', '1127121421-aPHZHQ5BCUoqfHER2UYhQYUEm0zPEMr9xJYizXl');
xhr.setRequestHeader('oauth_version', '1.0');
}
});
I calculated the signature values from the Twitter OAuth tool ..
This gives me 400 Bad Request error ....
Please let me know what the problem is...
The problem is your request's header, it should be like this:
xhr.setRequestHeader('Authorization','OAuth oauth_consumer_key="HdFdA3C3pzTBzbHvPMPw", oauth_nonce="4148fa6e3dca3c3d22a8315dfb4ea5bb", oauth_signature="uDZP2scUz6FUKwFie4FtCtJfdNE%3D", oauth_signature_method="HMAC-SHA1", oauth_timestamp= "1359955650", oauth_token, "1127121421-aPHZHQ5BCUoqfHER2UYhQYUEm0zPEMr9xJYizXl", oauth_version="1.0"');
Btw, this javascript library might help you on OAuth's stuff: oauth-1.0a
It support both client side and node.js
Cheers
The oauth_* fields are all part of the Authorization header string, so they need to be concatenated as shown at the bottom of this page - https://dev.twitter.com/docs/auth/authorizing-request
They should not be presented as separate header fields.
how come when I send ajax request like this everything works
$(".btnDeleteSong").click(function () {
var songId = $(this).attr('name');
$.ajax({
type: 'POST',
url: "/Home/DeleteSong/",
data: { id: songId },
success: ShowMsg("Song deleted successfully"),
error: ShowMsg("There was an error therefore song could not be deleted, please try again"),
dataType: "json"
});
});
But when I add the anonymous function to the success It always showes me the error message although the song is still deleted
$(".btnDeleteSong").click(function () {
var songId = $(this).attr('name');
$.ajax({
type: 'POST',
url: "/Home/DeleteSong/",
data: { id: songId },
success: function () { ShowMsg("Song deleted successfully"); },
error: function () {
ShowMsg("There was an error therefore song could not be deleted, please try again");
},
dataType: "json"
});
});
what if i wanted few things on success of the ajax call, I need to be able to use the anonymous function and I know that's how it should be done, but what am I doing wrong?
I want the success message to show not the error one.
function ShowMsg(parameter) {
$("#msg").find("span").replaceWith(parameter);
$("#msg").css("display", "inline");
$("#msg").fadeOut(2000);
return false;
}
Make sure your action is returning Json data.
"json": Evaluates the response as JSON and returns a JavaScript object. In jQuery 1.4 the JSON data is parsed in a strict manner; any malformed JSON is rejected and a parse error is thrown. (See json.org for more information on proper JSON formatting.)
http://api.jquery.com/jQuery.ajax/
Your action method should surely return Json data. I have the similar code see if that helps.
public ActionResult GetAllByFilter(Student student)
{
return Json(new { data = this.RenderPartialViewToString("PartialStudentList", _studentViewModel.GetBySearchFilter(student).ToList()) });
}
$("#btnSearch").live('click',function () {
var student = {
Name: $("#txtSearchByName").val(),
CourseID: $("#txtSearchByCourseID").val()
};
$.ajax({
url: '/StudentRep/GetAllByFilter',
type: "POST",
data: JSON.stringify(student),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(result) {
$("#dialog-modal").dialog("close");
RefreshPartialView(result.data);
}
, error: function() { alert('some error occured!!'); }
});
});
Above code is used to reload a partial view. in your case it should be straight forward.
Thanks,
Praveen