In a view of my project i'm doing an xhr request to a yii2 controller
The request is structured like this in my view
var xhr = new XMLHttpRequest();
xhr.open('POST', '$urlToController', true);
xhr.setRequestHeader("Content-type","application/json");
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.onreadystatechange = function () {
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
console.log(xhr.responseText);
}
};
// Print on console first
console.log({ id: JSON.stringify($('#grid').yiiGridView('getSelectedRows')), _csrf : csrfToken});
xhr.send({ id: JSON.stringify($('#grid').yiiGridView('getSelectedRows')), _csrf : csrfToken}});
and this is my controller:
public function actionTargetController() {
if(Yii::$app->request->isAjax) {
Yii::$app->response->format = Response::FORMAT_JSON;
if (Yii::$app->request->isPost) {
$post = Yii::$app->request->post();
return $post; // Print $post
}
}
}
When i try to send the data with xhr.send() i don't receive nothing in the yii2 controller and the response i get is always '[]' (empty array)
I've also tried to send data with the FormData Object but the result is the same.
Where am i doing wrong? Thanks in advance for all the help
PS:
_csrf param isn't pass either so i've disabled csrf validation in the beforeAction method.
Change the mime type and change the data that you post.
var xhr = new XMLHttpRequest();
xhr.open('POST', '$urlToController', true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); // <------ other mime type
xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
xhr.onreadystatechange = function () {
if(xhr.readyState === XMLHttpRequest.DONE && xhr.status === 200) {
console.log(xhr.responseText);
}
};
var params = $('#grid').yiiGridView('getSelectedRows')
.map(function (value) { return "selectedRowIds[]=" + value; }).join("&");
xhr.send("_csrf=" + csrfToken + (params ? "&" + params : ""));
Now you could get the posted data in the action with:
$post = Yii::$app->request->post('selectedRowIds');
You get an array of integers.
You could use jQuery for this too, since you're using it already. Much easier:
var params = {selectedRowIds: $('#grid').yiiGridView('getSelectedRows'), _csrf : csrfToken};
$.post('$urlToController', params).done(function(data) {
console.log(data);
})
Related
How can I check if the response received from XMLHTTPRequest has a particular class or not?
async function swipeAction(currentElementObj) {
var cardId = currentElementObj.getAttribute("value");
var dataString = {'card': cardId};
let response = await new Promise(resolve => {
var xhr = new XMLHttpRequest();
xhr.open("POST", "processes/explore.php", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify(dataString));
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
// I WANT TO CHECK SOMETHING LIKE THIS
if(xhr.response.getElementById("matched").classList.contains('matched'))
alert(xhr.response.getElementById("matched").classList);
}
}
});
}
In the response received, I want to check if the element with id matched has a class name matched or not. However, the above code isn't working. What should be the proper approach here?
If you're expecting plain text/html response from the server then processing it may look like that:
async function swipeAction(currentElementObj) {
var cardId = currentElementObj.getAttribute("value");
var dataString = { card: cardId };
let response = await new Promise((resolve, reject) => {
try {
var xhr = new XMLHttpRequest();
xhr.open("POST", "processes/explore.php", true);
xhr.setRequestHeader("Content-Type", "application/json");
// add responseType = "document" for response to be parsed into DOM
xhr.responseType = "document";
// override response mime type (in case your server sends text/plain)
xhr.overrideMimeType("text/html");
xhr.send(JSON.stringify(dataString));
xhr.onreadystatechange = function () {
// check for non-empty responseXML property
if (xhr.readyState == 4 && xhr.status == 200 && xhr.responseXML) {
const matched = xhr.responseXML.getElementById("matched");
if (!matched) return reject("Element not found in response");
if (matched) {
alert(matched.classList.contains("matched"));
resolve(true);
}
} else {
return reject("Incompatible response format");
}
};
} catch (e) {
reject(e.toString());
}
});
}
this is not sending any data from crome extension,i am trying to send json string to the server with mentioned url which says none type object has been returned,
var xhr = new XMLHttpRequest();
var ur = "http://127.0.0.1:8080/animal";
var dat = {"subject":"subject"};
xhr.open("POST", ur, true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
// do something with response
console.log(xhr.responseText);
}
};
xhr.send(dat);
}
};
xhr.send(dat);
You can't send an object with xhr.send(), you need to serialize it.
var dat = 'subject=subject';
I know I could just do this with a global, but I'd like to be object oriented if I can. If my request response returns a false for that 'ok' value, I'd like to log the data that was originally posted. Is that data accessible by a listener function on the request object?
Thanks!
function reqListener () {
var data = this.responseText;
var jsonResponse = JSON.parse(data);
if (jsonResponse['ok'] == false) {
//Here I want to log the data that I originally posted
console.log(__TheFormDataThatWasPassedtoSend__);
}
}
var xhr = new XMLHttpRequest();
xhr.addEventListener("load",reqListener);
xhr.open('POST',urltopostto, true);
// Set up a handler for when the request finishes.
xhr.onload = function () {
if (xhr.status === 200) {
// File(s) uploaded.
console.log('Uploaded');
} else {
alert('An error occurred!');
}
};
xhr.send(formData);
So the problem you have is needing to use data known when you create the eventListener when the eventListener actually fires. Below is your code to do this with formData
function reqListener (formData) {
var data = this.responseText;
var jsonResponse = JSON.parse(data);
if (jsonResponse['ok'] == false) {
console.log(formData);
}
}
var xhr = new XMLHttpRequest();
xhr.addEventListener("load", function() { reqListener.call(this,formData) });
xhr.open('POST',urltopostto, true);
// Set up a handler for when the request finishes.
xhr.onload = function () {
if (xhr.status === 200) {
// File(s) uploaded.
console.log('Uploaded');
} else {
alert('An error occurred!');
}
};
xhr.send(formData);
i try to send data via PUT method, but Laravel 5.5 do not see any data inside Input (or Request) on destination controller.
Here JS:
function selectProject(option){
console.log('Update selected');
var data = new Object();
data.project_id = option.value;
data.user_id ={{auth()->user()->id}};
console.log(data);
var url = "/admin/projects";
var xhr = new XMLHttpRequest();
xhr.open("PUT", url+'/update_selected', true);
xhr.setRequestHeader("X-CSRF-TOKEN", "{{ csrf_token() }}");
xhr.onload = function () {
var response = xhr.responseText;
if (xhr.readyState == 4 && xhr.status == "200") {
console.log(response);
document.getElementById("app").innerHTML = response;
} else {
console.log(response);
document.getElementById("app").innerHTML = response;
}
}
xhr.send(data);
}
inside Laravel controller i try to showing inputs:
echo '[Controller]Inputs:';
return Input::all();
Here output from console.log:
Update selected
{…}
project_id: "4"
user_id: 1
__proto__: Object { … }
[Controller]Inputs:[]
Question: what i'am doing wrong and where is inputs data?
p.s. I can use only pure javascript, no jQuery or anothers.
Problem solved by adding header:
xhr.setRequestHeader("content-type", "application/json");
and wrapping data to JSON:
xhr.send(JSON.stringify(data));
I have a one variable file like this.
var geography = [
{ id:"Country", header:"", width:150},
{ id:"Capital", header:"Capital", width:150},
{ id:"Falg", header:"Falg", width:150},
{ id:"Language", header:"Language", width:150},
{id:"Population", header:"Population", width:150},
],
Now I wanted to load this data from the json. I placed this data into JSON file and Using this code.
getGeography function(){
var geography;
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "data.json",true);
}
Now from here how to store into a variable and return that.
It should be read when the ready state of xmlhttp is 4 and response status is 200. You should parse the response with JSON.parse(). However you can't return the value from the function. Because XMLHTTPRequest is asynchronous by default.
function getGeography() {
var geography;
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "data.json",true);
xmlhttp.onreadystatechange = function () {
if(xmlhttp.readyState === 4 && xmlhttp.status === 200) {
geography = JSON.parse(xmlhttp.responseText;)
}
}
}
Instead of returning geography you have to programmatically read the value of geography when the AJAX request is complete. Something like this (read this):
Instead of writing code like this:
function anotherFunc() {
var geography = getGeography();
thenDoSomething(geography);
}
Write like this:
function anotherFunc() {
getGeography();
}
function getGeography() {
var geography;
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", "data.json",true);
xmlhttp.onreadystatechange = function () {
if(xmlhttp.readyState === 4 && xmlhttp.status === 200) {
geography = JSON.parse(xmlhttp.responseText);
thenDoSomething(geography);
}
}
}
It's like handing over the control of execution of rest of the code to getGeography() function, instead of expecting a return value from the function and then using that value. The getGeography() function resumes execution of rest of the code with the value received from AJAX response, when the AJAX call completes.
I'm not a fan of jQuery but in this case, you would probably benefit from this.
$.get( "ajax/test.html", function( data ) {
// data is your result
console.log(data);
console.log(JSON.parse(data));
});
https://api.jquery.com/jquery.get/
Here is how to use XMLHttRequest() :
<script>
const req = new XMLHttpRequest();
var geography = [];
req.onreadystatechange = function(event) {
// XMLHttpRequest.DONE === 4
if (this.readyState === XMLHttpRequest.DONE) {
if (this.status === 200) {
geography = JSON.parse(this.responseText);
console.log(geography);
alert("Great Success : check console !");
} else {
alert("Something has gone really Bad !");
}
}
};
req.open('GET', 'data.json', true);
req.send(null);
Be careful to use correct JSON :
[
{"id":"Country","header":"","width":150},
{ "id":"Capital","header":"Capital", "width":150},
{ "id":"Falg","header":"Falg","width":150},
{ "id":"Language","header":"Language", "width":150},
{ "id":"Population", "header":"Population", "width":150}
]