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?
Related
I made my own REST API with php coding and mySQL database. There is no Authentication. Just a GET call should retrieve mySQL table rows.
<?php
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
$servername = "xxxx.epizy.com";
$username = "xxxx";
$password = "yyyy";
$database = "xxxx_30758786_qwerty";
// Create connection
$conn = new mysqli($servername, $username, $password,$database);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}else{
$id = (isset($_GET['id']) && $_GET['id']) ? $_GET['id'] : '0';
if($id !='0'){
$stmt = $conn->prepare("SELECT * FROM users WHERE id = ?;");
$stmt->bind_param("i", $id);
}else{
$stmt = $conn->prepare("SELECT * FROM users");
}
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows > 0){
$userRecords=array();
$userRecords["users"]=array();
while ($user = $result->fetch_assoc()) {
extract($user);
$userDetails=array(
"id" => $id,
"full_name" => $full_name,
"email"=> $email,
"password" => $password,
"phone"=> $phone
);
array_push($userRecords["users"], $userDetails);
}
http_response_code(200);
//echo json_encode($userRecords);
echo json_encode($userRecords);
}else{
echo "failed";
//echo json_encode(array("message" => "No item found."));
}
}
$conn->close();
?>
http://qwerty.42web.io/um/users/read
While executing the API call from browsers (firefox / chrome) it works well. Below are the headers of Firefox browser call.
Response Headers:
Access-Control-Allow-Origin *
Cache-Control max-age=0
Connection keep-alive
Content-Encoding gzip
Content-Type application/json; charset=UTF-8
Date Mon, 18 Apr 2022 18:12:31 GMT
Expires Mon, 18 Apr 2022 18:12:31 GMT
Server nginx
Transfer-Encoding chunked
Vary Accept-Encoding
Request Headers
Accept text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Connection keep-alive
Host qwerty.42web.io
Upgrade-Insecure-Requests 1
User-Agent Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:99.0) Gecko/20100101 Firefox/99.0
But when I am executing through client software, it is not working. Instead of showing the JSON object, It is displaying a HTML content.
Headers while using a client software like POSTMAN / SoapUI:
Response Headers
HTTP/1.1 200 OK
Server=nginx
Date=Mon, 18 Apr 2022 18:14:45 GMT
*Content-Type=text/html*
Transfer-Encoding=chunked
Connection=keep-alive
Vary=Accept-Encoding
Expires=Thu, 01 Jan 1970 00:00:01 GMT
Cache-Control=no-cache
I noticed the response content type is text/html instead of application/json.
It is also dumping a HTML content with some javascript code. Output of that code is only a blank page.
I tried several type of headers, copied exactly same headers as of Browsers, nothing seems to work. Instead of a JSON object it always receives an HTML page. I spent at least 48 hours in troubleshooting my PHP code, GET request headers, different API clients.
Why the browser is able to parse my API response but not the API clients?
If you check the code that returns the request when you use Postman is that the Client needs to have Javascript enabled.
"This site requires Javascript to work, please enable Javascript in your browser or use a browser with Javascript support"
Postman is not a Browser.
It seems that the "problem" is originated in the Nginx server.
Some servers are configured to accept requests only from certain clients (Browsers, curl) and in your case they do not allow Postman/SoapUI.
Maybe the solution is to use COOKIES in Postman somehow.
Good day!
I have video server with different streams and server which clients are communicating with. My goal is to make a script going to specific stream on request, taking a chunk of data and returnig this chunk to client.
My idea is similar with this: to use cURL for authorization, capture some raw data and create callback function echoing data every chunk.
Problem is I've failed to find any mentions of using cURL with "endless data"; when I try it with my script it just goes to forever loading then crash with 504 error from nginx.
I don't understand what the difference for cURL between my data and "30 million characters long", if I use buffersize and flush() as well.
With no more introductions, here is my code:
public function callback($curl, $data)
{
ob_get_clean();
if (($data === false) || ($data == null))
{
throw new Exception (curl_error($curl) . " " . curl_errno($curl));
}
$length = strlen($data);
header("Content-type: video/mp4");
header("Transfer-encoding: chunked");
header("Connection: keep-alive");
header("Cache-Control: max-age=2592000, public");
header("Expires: ".gmdate('D, d M Y H:i:s', time()+2592000) . ' GMT');
header("Last-Modified: ".gmdate('D, d M Y H:i:s', #filemtime($this->path)) . ' GMT' );
echo $data;
ob_flush();
flush();
return $length;
}
public function getStreamChunk($camera_id)
{
$url = "http://example.com/$camera_id:0:0?format=mp4"; //url of noted video server
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $url,
CURLOPT_HEADER => 0,
CURLOPT_USERPWD => "$this->login:$this->pass",
CURLOPT_BUFFERSIZE => (1024*1024),
CURLOPT_WRITEFUNCTION => array($this, "callback")
)
);
curl_exec($curl);
curl_close($curl);
}
It workes for pictures (from the same server), there's no echo for cURL errors, so problem in infinite source and, I suspect, in headers. I've checked headers for responce from video server via browser, but can't find any overlooked mistake in my solution.
Here's headers from video server:
Response Headers
Connection: keep-alive
Content-Type: video/mp4
Date: Wed, 30 May 2018 07:31:34 GMT
Server: nginx/1.12.2
Transfer-Encoding: chunked
Request Headers
Accept: */*
Accept-Encoding: identity;q=1, *;q=0
Accept-Language: ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7
Authorization: Basic <...>
Connection: keep-alive
Cookie: <...>
Host: <...>
Range: bytes=0-
Referer: http://example.com/$camera_id:0:0?format=mp4
User-Agent: <...>
Solutions from here I also tried, but
1) I've already explained my problem with "30 million characters" answer C:
2) Solution with HTTP_RANGE isn't working for me as well (I tried) because of same error: long loading and crash.
UPD. I think I missed "Content-Range:" header; in the end you can use it without knowing size, like this: "bytes 1024-2047/*", but can't figure out how to use it properly in my case yet.
I've figured out what's the problem.
My code is working, there's no need for any other headers, except for cURL option:
CURLOPT_FOLLOWLOCATION => 1
So yeah, cURL CAN work with infinite data. Here's working solution for video proxing via cURL, if anyone else is interested.
I am trying to get twitter posts following this tutorial:
https://www.youtube.com/watch?v=tPrsVKudecs
there aren't a lot of tutorials regarding this online, and twitters console doesn't support running queries anymore as far as I understood.
any idea why this is happening?
This is the output I get in the Chrome "Network":
Remote Address:54.666.666.666:80
Request URL:http://666.com/yh/test/tweets_json.php
Request Method:GET
Status Code:500 Internal Server Error
Response Headers
view source
Connection:close
Content-Length:0
Content-Type:text/html
Date:Mon, 15 Jun 2015 13:51:40 GMT
Server:Apache/2.4.7 (Ubuntu)
X-Powered-By:PHP/5.5.9-1ubuntu4.5
Request Headers
view source
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
Host:666.com
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.124 Safari/537.36
Any ideas why this is happening?
Is there a better simple way to do it?
EDIT:
tweets_json.php
<?php
require 'tmhOAuth.php'; // Get it from: https://github.com/themattharris/tmhOAuth
// Use the data from http://dev.twitter.com/apps to fill out this info
// notice the slight name difference in the last two items)
$connection = new tmhOAuth(array(
'consumer_key' => '',
'consumer_secret' => '',
'user_token' => '', //access token
'user_secret' => '' //access token secret
));
// set up parameters to pass
$parameters = array();
if ($_GET['count']) {
$parameters['count'] = strip_tags($_GET['count']);
}
if ($_GET['screen_name']) {
$parameters['screen_name'] = strip_tags($_GET['screen_name']);
}
if ($_GET['twitter_path']) { $twitter_path = $_GET['twitter_path']; } else {
$twitter_path = '1.1/statuses/user_timeline.json';
}
$http_code = $connection->request('GET', $connection->url($twitter_path), $parameters );
if ($http_code === 200) { // if everything's good
$response = strip_tags($connection->response['response']);
if ($_GET['callback']) { // if we ask for a jsonp callback function
echo $_GET['callback'],'(', $response,');';
} else {
echo $response;
}
} else {
echo "Error ID: ",$http_code, "<br>\n";
echo "Error: ",$connection->response['error'], "<br>\n";
}
// You may have to download and copy http://curl.haxx.se/ca/cacert.pem
tmhOAuth.php: https://github.com/themattharris/tmhOAuth/blob/master/tmhOAuth.php
and this pem key: http://curl.haxx.se/ca/cacert.pem
All three in the same folder
In the tutorial it should run the query and get the json output.
I get a blank page.
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.
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'}