Understanding how XMLHttpRequest sends data to a server - php

I haven't understand data transfer to the server completely. Which ways do I have? When I started learning PHP, I thought there are two ways called GET which encrypts data in the URL and POST which sends data in another way to the server. I didn't know where exactly, though.
Now I want to learn about RESTful server backends, and I learned that GET and POST are just request methods, among others like PUT and DELETE, which doesn't seem to have anything to do with how data is transferred to the server.
Moreover, I read that additional data can be sent in the HTTP header. Is this how POST actually sends its data or is there even a difference?
I would like to either read POST data regardless of the request method using PHP's $_POST array, but this doesn't work. On the other hand, when I try to manually parse the header information from php://input, I cannot see POST data. Could someone please explain to me where data is transferred in the different cases?
My goal is to get parameters from the client regardless of content type, which may be form-data, json or something other, and request method. How can I do this in PHP? Requests will be sent using JQuery's AJAX functionality.

To explain how does http work using nc
http://linux.die.net/man/1/nc
GET
$ nc -l 8888 to start a dummy server listen at 8888
send a GET request using jQuery (impl via XHR)
$.get("http://localhost:8888", { a :1 ,b: 2})
nc would print what XHR sent to server to stdout
$nc -l 8888
GET /?a=1&b=2&_=1383234919249 HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Accept: */*
Origin: http://stackoverflow.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
DNT: 1
Referer: http://stackoverflow.com/questions/19710815/understanding-how-xmlhttprequest-sends-data-to-a-server
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4
thus, PHP parse GET /?a=1&b=2&_=1383234919249 into $_GET
POST
using nc to recording POST
POST / HTTP/1.1
Host: localhost:8888
Connection: keep-alive
Content-Length: 7
Accept: */*
Origin: http://stackoverflow.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36
Content-Type: application/x-www-form-urlencoded
DNT: 1
Referer: http://stackoverflow.com/questions/19710815/understanding-how-xmlhttprequest-sends-data-to-a-server
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4
a=1&b=2
here you can see Content-Type: application/x-www-form-urlencoded
,which tell the http body sent by browser is form encoded
as a result, PHP parse a=1&b=2 in to array $_POST
WHY php://input can't see POST BODY
according to http://php.net/manual/en/wrappers.php.php
php://input is a stream and can be read only once
below is from php doc
Note: A stream opened with php://input can only be read once; the
stream does not support seek operations. However, depending on the
SAPI implementation, it may be possible to open another php://input
stream and restart reading. This is only possible if the request body
data has been saved. Typically, this is the case for POST requests,
but not other request methods, such as PUT or PROPFIND.

Related

Bigcommerce api no response

I have some trouble getting a response from the new Bigcommerce api, not sure what I'm doing wrong.
Followed the instructions to get an Oauth token upon app install here:
developer.bigcommerce.com/apps/callback
The token is stored and used to make this request:
https://api.bigcommerce.com/stores/{store hash}/v2/time
According to developer.bigcommerce.com/api/authentication:
I've added X-Auth-Client and X-Auth-Token respectively as the app client ID and Oauth token.
The server is just returning "0 NO RESPONSE" and I'm not sure what's wrong. It does return unauthorized if I remove one of the headers though.
Does anyone have an idea on this? Thank you.
--
I'm using the Advanced Rest Client app from chrome to test for responses. Basically calling my store's URL api.bigcommerce.com/stores/3t984h/v2/time as a GET request and passing X-Auth-Client and X-Auth-Token headers.
Request headers
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.153 Safari/537.36
X-Auth-Client: p1r37bt131z86675nofv9xmhietoe4t
X-Auth-Token: kzm1q2w8h11dfkgbxhg3j0i8amac86g
Accept: */*
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en,zh;q=0.8,zh-TW;q=0.6,ko;q=0.4,en-GB;q=0.2,en-US;q=0.2
Finally got it. It was a spec issue which wasn't that obvious (to me at least).
According to this (https://developer.bigcommerce.com/api/headers)
I needed to add
Content-Type: application/json
Accept: application/json
to the request header for it go thru.

Cookie values not being sent in POST request from SWF

I have a SWF file which allows a user to upload files on my website. That SWF sends a POST request to upload.php on my server, thus uploading the file.
But before it does so, at upload.php I wanna make sure that the person who is doing this is signed in. For this currently, I check the SID cookie value sent in the request headers and check an entry against that SID value in my database (i store sessions in database). I works well for chrome but fails in firefox as it doesn't send any cookie headers when request is generated by the SWF.
How should I go about it. Thanks for help.
Headers sent in Chrome
Content-Length: 355894
Origin: http://localhost
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.52
Content-Type: multipart/form-data; boundary=----------ei4Ij5ae0ae0ei4Ef1Ef1KM7GI3Ef1
Accept: */*
Referer: http://localhost/home Accept-Encoding: gzip,deflate,sdch Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
Cookie: PHPSSID = 238e320eewbjdbew923e092ejhwbjhwebd
Headers sent in FireFox
Accept: text/*
Content-Type: multipart/form-data; boundary=----------GI3Ef1Ef1ae0GI3cH2Ef1Ef1cH2KM7
User-Agent: Shockwave Flash
Host: localhost
Content-Length: 355894
Connection: Keep-Alive
Cache-Control: no-cache
It's a feature of Chrome, but not a Bug of FireFox. Uploading SWF's must explictly send browser cookies. Look at FancyUpload starting from version 3.0.
Also note, PHP with suhosin can remove session variables if User-Agent header is not equal to the browsers. This called 'Session Fixtion'. So Uploading SWF's must send browsers User-Agent during requests too (or just disable suhosin patch).

Display HTTP Response on Webpage using PHP

I am looking to put together a website that displays the full HTTP Request Headers and HTTP Response Headers for the loading of the page itself. For instance. If someone browses to http://example.com/index.php , I want the following to display:
HTTP Request
GET /index.php HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.2.16) Gecko/20110319 Firefox/3.6.16
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
HTTP Response
HTTP/1.1 200 OK
Date: Mon, 21 Dec 2011 10:20:46 GMT
Server: Apache/2.2.15 (Red Hat)
X-Powered-By: PHP/5.3.3
Content-Length: 1169
Connection: close
Content-Type: text/html; charset=UTF-8
We were able to get the Request header to display fairly simply using the following PHP code:
print $_SERVER['REQUEST_METHOD']." ".$_SERVER['REQUEST_URI']." ".$_SERVER['SERVER_PROTOCOL']."<br>";
foreach (apache_request_headers() as $name => $value)
echo "$name: $value<br>";
But are having some difficulties with the HTTP Response header. Anyone have any ideas of how we can do this? It does not have to be PHP if you have a method that works in Perle or CGI or whatever.
To be clear, I don't mean to set the HTTP Response to anything specific, only display the response served by the web server to load the page.
You want to use headers_list()
http://www.php.net/manual/en/function.headers-list.php
headers_list() will return a list of headers to be sent to the browser / client. To determine whether or not these headers have been sent yet, use headers_sent().
Well here is the issue, the response header is generated after the PHP (or any server-side language for that matter) has already completed its job.
To put it in english its like the post man handing you a letter and you asking him to explain how the process of handing you the letter went. He will probably just look at you dumb.
You will need a client-side language (ie. JavaScript) to perform this task.
Use PHP to get the headers sent to the web Server.
http://www.php.net/manual/en/function.apache-request-headers.php
Use JavaScript to get headers sent by the web server. I would suggest using jQuery for that.
http://api.jquery.com/jQuery.ajax/#jqXHR
This way you are sure that you get all the headers which are either received by the web server or the browser.
Check out get_headers in PHP Manual

How does PHP access information about the client's browser?

How is it possible for client browser data to be saved in an array in PHP?
PHP runs on the server side, so I don't understand how it has access to information about the client's browser.
User agent data is usually sent with every HTTP requests, in the User-Agent HTTP header field. You might want to read up on HTTP message formats in general. For example, this is part of the HTTP request that my browser sent to load jQuery on this very page:
GET http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js HTTP/1.1
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Connection: keep-alive
If-Modified-Since: Fri, 01 Apr 2011 21:23:55 GMT
Accept-Charset: UTF-8,*;q=0.5
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.60 Safari/534.24
Accept: */*
PHP reads the client browser data that you're asking about from the User-Agent header field.
The client sends data to the server which the server uses to build the array (I'm assuming you're talking about $_GET, $_POST, $_SERVER, etc.)
You will find it here
$_SERVER['HTTP_USER_AGENT']
You may need to parse this by regex to get the browser name and version separately.
$_REQUEST
An associative array that by default contains the contents of $_GET, $_POST and $_COOKIE.
The data is submited by the browser when a new page is requested, PHP just puts it into an array for your convenience.
You should start by reading a bit about HTTP (GET and POST to begin with), and HTTP headers.

Can a cURL based HTTP request imitate a browser based request completely?

This is a two part question.
Q1: Can cURL based request 100% imitate a browser based request?
Q2: If yes, what all options should be set. If not what extra does the browser do that cannot bee imitated by cURL?
I have a website and I see thousands of request being made from a single IP in a very short time. These requests harvest all my data. When looked at the log to identify the agent used, it looks like a request from browser. So was curious to know if its a bot and not a user.
Thanks in advance
This page has all the answers to your questions. You can imitate the things mostly.
R1 : I suppose, if you set all the correct headers, that, yes, a curl-based request can imitate a browser-based one : after all, both send an HTTP request, which is just a couple of lines of text following a specific convention (namely, the HTTP RFC)
R2 : The best way to answer that question is to take a look at what your browser is sending ; with Firefox, for instance, you can use either Firebug or LiveHTTPHeaders to get that.
For instance, to get this page, Firefox sent those request headers :
GET /questions/1926876/can-a-curl-based-http-request-imitate-a-browser-based-request-completely HTTP/1.1
Host: stackoverflow.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.9.2b4) Gecko/20091124 Firefox/3.6b4
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 115
Connection: keep-alive
Referer: http://stackoverflow.com/questions/1926876/can-a-curl-based-http-request-imitate-a-browser-based-request-completely/1926889
Cookie: .......
Cache-Control: max-age=0
(I Just removed a couple of informations -- but you get the idea ;-) )
Using curl, you can work with curl_setopt to set the HTTP headers ; here, you'd probably have to use a combination of CURLOPT_HTTPHEADER, CURLOPT_COOKIE, CURLOPT_USERAGENT, ...

Categories