Filter to detect if Response::json was sent - laravel

I have a filter. I want this filter to act only if the page is displaying HTML and NOT if it's json or any other format
App::after(function($request, $response)
{
if( $request->getMethod() == 'GET' && $request->getRequestFormat() == 'html' ) {
// do something!
}
});
In my Controller functions I return json data:
return Response::json($data);
However, $request->getRequestFormat() is still equal to 'html' and it shouldn't be.
I know that I can set the format to be 'json' like this:
Request::setRequestFormat('json');
return Response::json($data);
But it seems redundant. If I'm returning a Response::json it should know that it's json and not HTML. How can I detect that it's a Response::json?

The requestFormat is something that isn't set automatically - you either provide it programattically via setRequestFormat or by including a POST/GET parameter _format.
If you want to check if a request is JSON you can do $request->isJson(), but it looks more to me like you're trying to check if the response is JSON? In which case you can do $response instanceof Illuminate\Http\JsonResponse or $response->headers->get('Content-Type') == 'application/json'

This is not a json at all, it's HTML which contains some string inside a div. Remove the div and just pass the json using:
return Response::json($data);
Then in the client side, using jQuery parse the json data and create a div and append the data inside div, for example, in your success callback try something like this:
success(response) {
// Parse the json if not parsed by jQuery
var obj = $.parseJSON(response);
if(obj.success) {
$('<div/>', {id:"query-log"}).append(obj.data).appendTo('body');
}
}
This may not accurate with your json data but hope you got the idea, in short, just pass the json data to the client side and manipulate it in the browser using jQuery.
Update: The better approach would be to provide the dataType when making the request using something like tgis:
$.ajax({
dataType: "json",
url: url,
data: data,
success: function( data ) {
}
});
Also you may use this:
$.getJSON( "url", function( data ) {
// ...
});
So a request header will be sent to the server and you may check if the request is expecting a json response using this:
if($request->wantsJson()) {
//
}
This is the method in the request class:
/**
* Determine if the current request is asking for JSON in return.
*
* #return bool
*/
public function wantsJson()
{
$acceptable = $this->getAcceptableContentTypes();
return isset($acceptable[0]) && $acceptable[0] == 'application/json';
}

App::after(function($request, $response)
{
if( $request->getMethod() == 'GET' && $request->getRequestFormat() == 'html' ) {
// Test if response is JSON (PHP 5.3+ needed for this)
json_decode($response);
if ( json_last_error() != JSON_ERROR_NONE ) {
// Do something
}
}
});

Related

Cypress intercept call return body as object

I have the follwing code
cy.intercept({
method: "GET",
url: `**/features`
}).as("getFeatures");
cy.wait('#getFeatures').then(({response}) => {
if(response?.statusCode ===200){
expect(response.body.features).to.exist;
expect(response.body.features).to.contain('feature01');
// hier I would like to return the response.body oder response.body.features as an object to interact with the ui based on its value (wether the feature is activated or not)
}
})
Saving the body into a file is not an option because the tests will run in paralel and different tests may access invalid values of feature endpoint
EDIT: because I need this method more than once. I want to return the value of Body as an object the solution I am looking for is like
function visitUrl() : Object {
//intercept
return body
}
You can use alias and save the response body and use it later on.
cy.intercept({
method: 'GET',
url: `**/features`,
}).as('getFeatures')
cy.wait('#getFeatures').then(({response}) => {
if (response?.statusCode === 200) {
expect(response.body.features).to.exist
expect(response.body.features).to.contain('feature01')
cy.wrap(response.body.features).as('responseBodyFeatures')
}
})
cy.get('#responseBodyFeatures').then((features) => {
cy.log(features) //logs the features section from response body
})

Retrieve post variable sent via Ajax in Django

I'm processing a table of banking/statement entries that have been exported from another system via a CSV file. They are imported into a view and checked for duplicates before being presented to the user in a HTML table for final review.
Once checked they are sent via AJAX to the server so they can be added into a Django model. Everything is working OK including CSRF but I cannot access the POSTed variable although I can see it!
Unfortunately making a hidden form isn't viable as there are 80+ rows to process.
My Javascript looks like:
$.ajax({
type: 'POST',
url: '......./ajax/handleImports/',
data: entriesObj,
success: function (data) {
if (data.response && data.response) {
console.log("Update was successful");
console.log(data.entries)
} else { ... }
},
error: function() { ... }
where entriesObj is
var entriesObj = JSON.stringify({ "newentries": newEntries });
console.log(entriesObj)
and when dumped to console.log looks like:
{"newentries":[{"Include":"","Upload ID":"0","Date":"2019-01-09", ... }
Now in view.py when I return the whole request.POST object as data.entries using
context['entries'] = request.POST
return JsonResponse(context)
I get
{"{"newentries":[{"Include":"","Upload ID":"0","Date":"2019-01-09", ... }
but if I try and retrieve newentries with:
entries = request.POST.get('newentries', None)
context['entries'] = entries
return JsonResponse(context)
the console.log(data.entries) will output null?
How am I supposed to access the POSTed entriesObj?
The data is JSON, you need to get the value from request.body and parse it.
data = json.loads(request.body)
entries = data.get('newentries')

Cakephp 2.0 Ajax post data not showing in the controller?

I'm working cakephp web application, I have created a small Ajax function in default ctp file. setup file now I want to send value data to another controller function, in the chrome browser network showing that Ajax posting to desire url but in controller post value didn't show up when I try to echo $_post ['selectedlocation']??
Ajax Default File
var DisplayLocationName = $('#ListingLocation option:selected').val();
$.ajax({
type: "POST",
url: '/listings/home',
data: {selectedlocation:DisplayLocationName },
dataType:"text",
success: function(result) {
}
});
Listing Controller Function
function home()
{
if(!isset($this->params['requested']) || $this->params['requested'] != true)
{
$this->actionId = 'home';
}
$this->viewFile = null;
if($this->params['isAjax'] && isset($_POST['selectedlocation']))
{
echo "erreerreer";
echo $selectloc= $_POST['selectedlocation'];
$this->set('selectloc',$selectloc);
}
}
how do I display Ajax post value in default for testing purposes that, make sure me that Ajax is posting proper values to the controller
You will need to use the logging files to read the post data. This will write the data to the error log and you can view it there.
function home()
{
if(!isset($this->params['requested']) || $this->params['requested'] != true)
{
$this->actionId = 'home';
}
$this->viewFile = null;
if($this->params['isAjax'] && isset($_POST['selectedlocation']))
{
echo "erreerreer";
CakeLog::write('error', $this->request->data('selectedlocation));
echo $selectloc= $_POST['selectedlocation'];
$this->set('selectloc',$selectloc);
}
}
When you want to $_POST a data from an ajax request, you should use:
$form_data = $this->request->data; (cakephp 2.x)
$form_data = $this->params['form'] (cakephp 1.3)
Now you got an array with your $_POSTed data, try to var_dump() it to understand its sctructure if you want.

How to send call to JSP from AJAX?

This servlet code,here 1st i want to send return message(if message!=null) to the Ajax for alert and 2nd one if message==null i want to call another jsp with pass the list to this jsp.
if(message!=null){
response.setContentType("text/plain");
response.getWriter().write(message);
}else{
JSONObject jobj = new JSONObject();
String urlToRedirect = "SearchEmployee.jsp";
jobj.put("url",urlToRedirect );
response.getWriter().write(jobj.toString());
}
Here i cant understand how to call this jsp url in else part
$.ajax({
type:"POST",
url:'../SearchEmployeeServlet',
data:$('#DisplayEmployeeListForm').serialize(),//$('form').serialize();
success:function(msg){
if(msg!=""){
alert(msg);
window.location.reload(true);
}else{
....here i want to call 2nd jsp
}
}
});
You could just forward the request server-side, to avoid needing the client to make a second request:
request.getRequestDispatcher("SearchEmployee.jsp").forward(request, response);
Or alternatively, you could send an HTTP redirect response, so the client should handle the redirection to the second request automatically:
response.sendRedirect(response.encodeRedirectUrl("SearchEmployee.jsp"));
Note that how you handle this in the JavaScript depends on the datatype you expect to receive from SearchEmployee.jsp. For example, if it is XML and you have set the response content-type to text/xml jQuery will parse it and pass you an XML DOM object to your success function:
success:function(msg) {
if (msg instanceof XMLDocument) {
// handle list
} else {
alert(msg);
window.location.reload(true);
}
}
If you're expecting HTML, this may be returned as a string, so you could test to see if your returned string starts with some HTML. For example, if your HTML will always start with a <ul> tag:
success:function(msg) {
if (msg.startsWith("<ul>")) { // note you may need to do msg = $.trim(msg) first
// handle list
} else {
alert(msg);
window.location.reload(true);
}
}
If you don't want to auto-forward as suggested above and you'd rather stick with your current approach, there are a few things you'll need to change.
Using if(msg!="") in your success function is bad as that will return true as long as the server does not return an empty response (so in both cases you'll get an alert).
The first thing to do is to add a content-type header to your servlet code to indicate you're returning JSON in the second case:
response.setContentType("application/json");
response.getWriter().write(jobj.toString());
Now when jQuery handles the response, it will attempt to parse it as JSON before calling the success function. As such, you can now test in your success function whether the argument jQuery has given you is an object or a string:
success:function(msg){
if (typeof msg === "object") {
// you got the JSON response
$.ajax({
url: msg.url,
// etc...
});
} else {
// you got the plain text response
alert(msg);
window.location.reload(true);
}
}
Just make the ajax request in else part as you did above.
$.ajax({url: "jsp url", success: function(result){
}});
Find more information here

not getting response from ajax call in codeigniter

I am trying to check if the user name is available for use using ajax and codeigniter. I have problem to get the response from the codeingniter controller in my js. file but without success.
Here is the controller function, relevant to the question:
if ($username == 0) {
$this->output->set_output(json_encode(array("r" => true)));
} else {
$this->output->set_output(json_encode(array("r" => false, "error" => "Username already exits")));
}
Rest assured that I do get 1 if username already exists in thedatabase and 0 if it does not exist.
I have the following js.file
// list all variables used here...
var
regform = $('#reg-form'),
memberusername = $('#memberusername'),
memberpassword = $('#memberpassword'),
memberemail = $('#memberemail'),
memberconfirmpassword = $('#memberconfirmpassword');
regform.submit(function(e) {
e.preventDefault();
console.log("I am on the beggining here"); // this is displayed in console
var memberusername = $(this).find("#memberusername").val();
var memberemail = $(this).find("#memberemail").val();
var memberpassword = $(this).find("#memberpassword").val();
var url = $(this).attr("action");
$.ajax({
type: "POST",
url: $(this).attr("action"),
dataType: "json",
data: {memberusername: memberusername, memberemail: memberemail, memberpassword: memberpassword},
cache: false,
success: function(output) {
console.log('I am inside...'); // this is never displayed in console...
console.log(r); // is never shonw in console
console.log(output); is also never displayed in console
$.each(output, function(index, value) {
//process your data by index, in example
});
}
});
return false;
})
Can anyone help me to get the username value of r in the ajax, so I can take appropriate action?
Cheers
Basically, you're saying that the success handler is never called - meaning that the request had an error in some way. You should add an error handler and maybe even a complete handler. This will at least show you what's going on with the request. (someone else mentioned about using Chrome Dev Tools -- YES, do that!)
As far as the parse error. Your request is expecting json data, but your data must not be returned as json (it's formatted as json, but without a content type header, the browser just treats it as text). Try changing your php code to this:
if ($username == 0) {
$this->output->set_content_type('application/json')->set_output(json_encode(array("r" => true)));
} else {
$this->output->set_content_type('application/json')->set_output(json_encode(array("r" => false, "error" => "Username already exits")));
}

Resources