I am developing a single page script i.e. category.php for category management.
This script have an input button to invoke AJAX call.
<input type="button" id="btn" />
Jquery code to bind click event and call ajax. I want json response.
$(document).ready(function(e) {
$('#btn').click(function(e) {
id=1;
jQuery.ajax({
type: 'post',
url: 'category.php',
success: function(data) {
if(data.rstatus==1){
alert(data.text);
}else
alert(data);
},
data:{'id':id}
});
});
});
A php code to entertain AJAX call.
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) &&
strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
$jsonResponse=array('rstatus'=>1,'id'=>$_POST['id']);
header("Content-type: application/json");
json_encode($jsonResponse);
die();
}
Problem:
This ajax call is unable to produce correct response in call back function, and cause error in firebug console.
TypeError: data is null
In FIREBUG Headers are as follow:
Response Headers
> Cache-Control no-cache, must-revalidate Connection Keep-Alive
> Content-Length 0 Content-Type application/json Date Tue, 26 Mar 2013
> 12:45:52 GMT Expires Mon, 26 Jul 1997 05:00:00 GMT
> Keep-Alive timeout=5, max=98 Last-Modified Tue, 26 Mar 2013
> 12:45:52GMT Pragma no-cache Server Apache/2.4.3 (Win32) OpenSSL/1.0.1c
> PHP/5.4.7 X-Powered-By PHP/5.4.7
Request Headers
> > Accept */* Accept-Encoding gzip, deflate
> > Accept-Language en-US,en;q=0.5 Content-Length 4
> > Content-Type application/x-www-form-urlencoded; charset=UTF-8
> > Cookie __gads=ID=39701a3d85dce702:T=1350383638:S=ALNI_MY_rHGVQ-qNxH4UGmbY_G-IuVcDkA;
> > __utma=141011373.593047819.1350426838.1364292528.1364295112.314;PHPSESSID=1s73cho6ildjt80jtudt8nq0f5 Host abc.com Referer http://www.abc.com/category.php
> > User-Agent Mozilla/5.0 (Windows NT 5.1; rv:19.0) Gecko/20100101
> > Firefox/19.0 X-Requested-With XMLHttpRequest
It's look like your response content is empty. You forgot an echo.
if(!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
$jsonResponse=array('rstatus'=>1,'id'=>$_POST['id']);
header("Content-type: application/json");
echo json_encode($jsonResponse);
die();
}
If you want to response a json, you must put it in the response content. In Php, you just have to use echo to put something in the response content.
This doesn't work simply because $_SERVER doesn't contain that information. All request headers aren't really stored there. Have a look at getallheaders (http://php.net/manual/en/function.getallheaders.php)
Edit: Oh, also you need to echo the response. $_SERVER may contain the information you need in this case, but it is not reliable and portable. I'd still advise you to use getallheaders
don't use HTTP_X_REQUESTED_WITH - barely works in jQuery
try to send additional var, like
data:{'id':id, 'request':'xmlhttprequest'}
Related
I am making a request through Guzzle 3.8.1 for a Jasper report (via the Jasper Server API) that is over 2MB and I'm getting a response with the correct Content-Length header but no response body.
Guzzle request:
GET /jasperserver/rest_v2/reports/projects/i3app_suite/Resource/BulkShiftExport.csv?ACCOUNT_ID=2&START_DATETIME=2015-01-01&END_DATETIME=2015-01-31 HTTP/1.1
Host: jasper.i3app:8080
User-Agent: Guzzle/3.8.1 curl/7.19.7 PHP/5.5.8
Authorization: Basic ***=
Response:
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Cache-Control: private
Expires: Wed, 31 Dec 1969 17:00:00 MST
P3P: CP="ALL"
Set-Cookie: JSESSIONID=F0B0F72B65A8145B45DA9DB2BACE53D8; Path=/jasperserver/; HttpOnly, userLocale=en_US;Expires=Fri, 13-Feb-2015 18:56:44 GMT;HttpOnly
Content-Disposition: attachment; filename="BulkShiftExport.csv"
output-final: true
Content-Type: application/vnd.ms-excel
Content-Length: 2173897
Date: Thu, 12 Feb 2015 18:57:02 GMT
If I make this request through curl on the command line (or request it in a browser) I get the report as expected
GET /jasperserver/rest_v2/reports/projects/i3app_suite/Resource/BulkShiftExport.csv?ACCOUNT_ID=2&START_DATETIME=2015-01-01&END_DATETIME=2015-01-30 HTTP/1.1
Authorization: Basic ***=
User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 NSS/3.15.3 zlib/1.2.3 libidn/1.18 libssh2/1.4.2
Host: jasper.i3app:8080
Accept: */*
< HTTP/1.1 200 OK
< Server: Apache-Coyote/1.1
< Cache-Control: private
< Expires: Wed, 31 Dec 1969 17:00:00 MST
< P3P: CP="ALL"
< Set-Cookie: JSESSIONID=AF1BF885354AF3E352DD9E18FA044A4B; Path=/jasperserver/; HttpOnly
< Set-Cookie: userLocale=en_US;Expires=Fri, 13-Feb-2015 19:03:42 GMT;HttpOnly
< Content-Disposition: attachment; filename="BulkShiftExport.csv"
< output-final: true
< Content-Type: application/vnd.ms-excel
< Content-Length: 2113902
< Date: Thu, 12 Feb 2015 19:03:49 GMT
<
{ [data not shown]
The only difference I could see was Accept: */* in the curl request. I tried adding that header to the guzzle request and got the same result.
When making the request through the Guzzle client it appears to take the same amount of time (5-6 seconds) to receive the response, and it sets the Content-Length header, but the response body is empty. Why am I getting an empty response body though Guzzle which is using curl but not when using curl on the command line? Is there an option I need to set to make this work?
$request = $this->getGuzzleClient()->createRequest('GET');
$config = $this->getConfig();
$url = new Url(
$config['scheme'],
$config['host'],
$config['user'],
$config['pass'],
$config['port'],
$config['path'] . $reportPath . '.' . $format,
new QueryString($parameters)
);
$request->setUrl($url);
$response = $request->send();
...
public function getGuzzleClient()
{
if (!$this->restClient) {
$client = new GuzzleClient();
$this->setRestClient($client);
}
return $this->restClient;
}
In my case, I was using MockHandler mistakenly.
The problem is that angularjs sends post data as json. There are several solutions:
Serverside:
Angularjs - Form Post Data Not Posted?
Clientside:
http://sebgoo.blogspot.de/2013/05/angularjs-post-data-to-php.html
More fancy one?:
http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/
I want to use the server side one:
PHP file:
<?php
$data = file_get_contents("php://input");
$errors['EncodeI']=$data->customerFirstName;
$data = json_decode($data, TRUE);
$errors['EncodeII']=$data['customerFirstName'];
echo return_sql2json($errors, $rows);//just a function which returns the error messages
?>
Js:
...
$http({
url: 'read.php',
method: "POST",
// headers : {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
params: {
customerFirstName: $scope.customerFirstName,
customerLastName: $scope.customerLastName,
customerEmail: $scope.customerEmail
}
}).success(function(data) {
....
My Header: The data customerFirstName is sent
Remote Address:::1:80
Request URL:http://localhost/360/app/read.php?customerEmail=aa&customerFirstName=aa&customerLastName=aa
Request Method:POST
Status Code:200 OK
Request Headersview source
Accept:application/json, text/plain, */*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:no-cache
Connection:keep-alive
Content-Length:0
Cookie:AccessKey=somePW; Email=someemail; PHPSESSID=somesession
Host:localhost
Origin:http://localhost
Pragma:no-cache
Referer:http://localhost/360/app/
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36
Query String Parametersview sourceview URL encoded
customerEmail:aa
customerFirstName:aa
customerLastName:aa
Response Headersview source
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:Keep-Alive
Content-Length:310
Content-Type:text/html
Date:Wed, 07 May 2014 11:21:46 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive:timeout=5, max=96
Pragma:no-cache
Server:Apache/2.4.9 (Win32) OpenSSL/0.9.8y PHP/5.4.27
X-Powered-By:PHP/5.4.27
And the Response:
errors: {EncodeI:null, EncodeII:null, customerFirstName:First Name is required,…}
EncodeI: null
EncodeII: null
customerEmail: "Email is required"
customerFirstName: "First Name is required"
customerLastName: "Last Name is required"
success: false
Conclusion: Not working. Also the server side solutions I didn't manage to be successful but they anyways look more complicated for me.
The answer is rename params into data.
Scenario: Playing an online game, have an javascript file that allows me to port data to a PHP on a server using POST/json. I have to enter the path of my server into my client PC for this to work. I am getting a confirmation that connection is fine.
The PHP only recognises source from the website I am playing on, and I can see data transferring to the site in my developer console. The data being POSTed is in the following format:
I can see the data coming in an array looking at the console:
Request URL: //xxxxxx.xxxx/aix/server_api.php Request Method:POST Status Code:200 OK Request Headersview source Accept:application/json, text/javascript, */*; q=0.01 Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3 Accept-Encoding:gzip,deflate,sdch Accept-Language:en-GB,en-US;q=0.8,en;q=0.6 Connection:keep-alive Content-Length:65236 Content-Type:application/x-www-form-urlencoded; charset=UTF-8 Host:sd.fast-page.org Origin:http://xx.yyy.com Referer:http://xxx.yyy.com/232/index.aspx User-Agent:Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Ubuntu Chromium/25.0.1364.160 Chrome/25.0.1364.160 Safari/537.22 Form Dataview sourceview URL encoded alliance[id]:118 alliance[name]:DS alliance[members]:12 alliance[score]:982078 data_type:city data[0][id]:12517457 data[0][owner_id]:1538 data[0][owner]:MM1 data[0][coords]:'081:191 data[0][name]:C31 4Chief data[0][score]:11020 data[0][city_type]:castle data[0][location]:land data[1][id]:12517458 data[1][owner_id]:1538 data[1][owner]:MM1 data[1][coords]:'082:191 data[1][name]:C31 5Redrum data[1][score]:10596 data[1][city_type]:castle data[1][location]:water data[2][id]:12386381 data[2][owner_id]:1538 data[2][owner]:MM1 data[2][coords]:'077:189 data[2][name]:C31 1Home data[2][score]:10460 data[2][city_type]:castle data[2][location]:land data[3][id]:12320847 data[3][owner_id]:1538 data[3][owner]:MM1 data[3][coords]:'079:188 data[3][name]:C31 6North data[3][score]:10182 data[3][city_type]:castle data[3][location]:land data[4][id]:12386382 data[4][owner_id]:1538 data[4][owner]:MM1 data[4][coords]:'078:189 data[4][name]:C31 3Back data[4][score]:10108 data[4][city_type]:castle data[4][location]:land data[5][id]:12517453 data[5][owner_id]:1538 data[5][owner]:MM1 data[5][coords]:'077:191 data[5][name]:C31 2Second data[5][score]:9968 data[5][city_type]:castle data[5][location]:land data[6][id]:12714060 data[6][owner_id]:1538 data[6][owner]:MM1 data[6][coords]:'076:194 data[6][name]:C31 MacoHub data[6][score]:9692 data[6][city_type]:castle data[6][location]:land data[7][id]:12517460 data[7][owner_id]:1538 data[7][owner]:MM1 data[7][coords]:'084:191 data[7][name]:C31 Tango data[7][score]:9163 data[7][city_type]:castle data[7][location]:land data[8][id]:12582993 data[8][owner_id]:1538 data[8][owner]:MM1 data[8][coords]:'081:192 data[8][name]:C31 Spring data[8][score]:8864 data[8][city_type]:castle data[8][location]:land data[9][id]:12517454 data[9][owner_id]:1538 data[9][owner]:MM1 data[9][coords]:'078:191 data[9][name]:C31 Pally data[9][score]:8816 data[9][city_type]:castle data[9][location]:land data[10][id]:12779603 data[10][owner_id]:1538
[and so on and so forth.....have masked the rest but this is the format
Response Headersview source Access-Control-Allow-Headers:Content-Type Access-Control-Allow-Methods:POST, GET, OPTIONS Access-Control-Allow-Origin: //xxx.yyy Access-Control-Max-Age:1000 Cache-Control:no-store, must-revalidate, max-age=0, proxy-revalidate, no-transform Connection:keep-alive Content-Encoding:gzip Content-Length:70 Content-Type:application/json Date:Fri, 29 Mar 2013 18:08:14 GMT Expires:Fri, 29 Mar 2013 18:08:14 GMT Pragma:no-cache Server:Apache Vary:Accept-Encoding X-Powered-By:PHP/5.5.0alpha5
Now what I see above is the output to the console on my PC when I trigger the client app.
The PHP is as follows:
$m = false;
if(preg_match('/http\:\/\/game url/',$_SERVER['HTTP_ORIGIN'],$m))
{ $m = $m[1]; }
if(empty($m)) { die('Invalid Origin.'); }
if(!empty($_POST['data_type']))
{
$sender = $_POST['sender'];
$alliance = $_POST['alliance'];
$request = $_POST['data_type'];
$data = $_POST['data'];
// Response to Alliance Info Exporter
$json = array(
'message' => 'recieved.',
'data' => array(),
'error' => false
);
// handle data types
switch($request)
{
case 'connection_test': $json['message'] = 'Welcome to our server. Your are connected!'; break;
case 'member' : /* Code for member request */ break;
case 'city' : /* Code for city request */ break;
case 'support' : /* Code for support request */ break;
default : $json['message'] = 'Nothing Done.'; break;
}
// set headers for API
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type');
header('Content-type: application/json');
// Respond
die(json_encode($json));
}
die('No Access.');
I have two or three problems here
I can't seem to manipulate the data that the PHP is getting at all
Whenever I try to add any arguments to the case statement just to even see if I can parse the data somehow then the api stops responding to my client
For example, at the city switch I just tried to output the data to a file just to confirm it was coming through because my browser console gives me a POST success code (http 200)
This is the code I used:
$f = fopen("city.txt", "w");
fwrite($f, $_POST);
fclose($f);
I tried it in the main part of my PHP, tried it at the city case switch (that is the type of query I am executing first), and I tried with other defined types like $data, etc. Nothing writes.
What am I doing wrong?
Secondly my endstate is to post this to a SQL server, how would I do that?
In Safari and Firefox, the response part of the code is not working (i.e. from PHP-->Ajax-->jQuery). The variables definitely make it to the PHP fine (tested using mail() ), so it's probably some small error on my behalf!
jQuery:
$.ajax({
type: "POST",
dataType: "json",
data: postData,
url: "http://www.kudiclub.com/test/login/?loginsub",
success: function(data){
if(data.success==false){
$("#login .error").html(data.reply).show();
$("#login-email").val(data.email);
$("#password").val("");
}else{
window.location = data.ref;
}
}
});
PHP:
$data = array('success' => false, 'reply' => 'Username and password did not match.', 'email' => $email);
print json_encode($data);
return;
Hoping somebody can help. Thanks, Nick.
SOLUTION
After much fiddling about, it turns out that it doesn't see a full URL as a relative path. Changing the url to '/test/login/?loginsub' did the trick.
The server says: Content-Type: text/html. Is not a json document (application/json).
http://www.kudiclub.com/test/login/?loginsub
GET /test/login/?loginsub HTTP/1.1
Host: www.kudiclub.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:13.0) Gecko/20100101 Firefox/13.0.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: es-es,es;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Cookie: PHPSESSID=060b8210adfb3c67ff792b9471c7fa1c
Cache-Control: max-age=0
HTTP/1.1 200 OK
Date: Thu, 02 Aug 2012 22:12:10 GMT
Server: Apache
X-Powered-By: PHP/5.2.17
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Keep-Alive: timeout=2, max=200
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: text/html
I am trying to send JSON data from a form using the XMLHttpRequest object. I can send the data using the following function. There are no errors displayed in FireBug and the JSON-data in the request is displayed well formed by FireBug.
However, I send the data to echo.php, what simply returns the content:
<?php
print_r($_POST);
print_r($_GET);
foreach (getallheaders() as $name => $value) {
echo "$name: $value\n";
}
echo file_get_contents('php://input');
?>
The POST-array is always empty, but I can see the JSON string returned by file_get_contents. How does that happen? What am I doing wrong?
output of echo.php
Array
(
)
Array
(
)
Host: localhost
User-Agent: Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:10.0.2) Gecko/20100101 Firefox/10.0.2
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: eo,de-de;q=0.8,de;q=0.6,en-us;q=0.4,en;q=0.2
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Type: application/json; charset=utf-8
Referer: http://localhost/form.html
Content-Length: 88
Cookie: {{..to much data..}}
Pragma: no-cache
Cache-Control: no-cache
{"type":"my_type","comment":"commented"}
the sending function:
function submit(){
var data={};
data.type=document.form.type.value;
data.comment=document.form.comment.value;
//get right XMLHttpRequest object for current browsrer
var x=ajaxFunction();
var string = JSON.stringify(data);
x.open('POST','echo.php',true);
x.setRequestHeader('Content-type','application/json; charset=utf-8');
x.setRequestHeader("Content-length", string.length);
x.setRequestHeader("Connection", "close");
x.onreadystatechange = function(){
if (x.readyState != 4) return;
if (x.status != 200 && x.status != 304) {
alert('HTTP error ' + req.status);
return;
}
data.resp = JSON.parse(x.responseText);
if(data.resp.status=='success'){
alert('That worked!');
}else{
alert('That didn\'t work!');
}
}
x.send(string);
return false; //prevent native form submit
}
PHP does not process JSON requests automatically like it does with form-encoded or multipart requests. If you want to use JSON to send requests to PHP, you're basically doing it correctly with file_get_contents(). If you want to merge those variables into your global $_POST object you can, though I would not recommend doing this as it might be confusing to other developers.
// it's safe to overwrite the $_POST if the content-type is application/json
// because the $_POST var will be empty
$headers = getallheaders();
if ($headers["Content-Type"] == "application/json")
$_POST = json_decode(file_get_contents("php://input"), true) ?: [];
Quick note: you should not be sending a charset with your Content-Type for application/json. This should only be sent with text/* Content-Types.
You forgot to name your variables in the send function.
The good way to use it is
x.send('name1='+string+'&name2=value2');
Given that, I think you will have to change the content-length header. I don't think it is usefull to send it.
One another thing you can do is try with GET method.
You can also try to change your content-type header by that one :
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded")