I met the RESTful ideology and I fell in love with it. However the only request methods supported by HTML forms so far are GET
and POST
, which is kind of sad, because this means that to use REST
as it's supposed to be used I need to use some work around which is likely to not be pretty, as it really is.
So the only way I found I can send PUT
or DELETE
requests is from the XhrHttpRequest
object in JavaScript.
How I send data seems pretty simple:
xhr = new XMLHttpRequest();
xhr.open('PUT' /*for example*/, URL, true);
xhr.send('MyData=HelloWorld');
Then on the other side I fetch the data:
class Input {
private static $input;
public static function init(){
parse_str(file_get_contents('php://input'), self::$input);
}
public static function data($key = null){
return $key ? self::$input[$key] : self::$input;
}
}
Input::init();
My concern is that the header Content-Type
is always text/plain;charset=UTF-8
no matter what the request type is, as opposed to using standard form submission, where Content-Type
becomes application/x-www-form-urlencoded
. I can of course put that on POST
requests as well but in this case what should I put on PUT
and DELETE
requests?
Are there any potential problems I may run into with browsers by using this nonstandard method of sending requests? Do you see any drawbacks in general, apart the one that users who don't run JavaScript will be unable to use my site?
P.S.: I was wondering, if it turned out OK to use this method, wouldn't it be more efficient and secure to use JSON
formatting to send data instead of the query string one I have shown in the example? I primarily want to avoid the query string format because I remember reading that JavaScript's URL encoding functions aren't the best.
1 Answer 1
You can set header fields with the .setRequestHeader
method, for example:
xhr = new XMLHttpRequest();
xhr.open('PUT' /*for example*/, URL, true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify({MyData: 'HelloWorld'});
JSON is a good format for receiving responses from a RESTful API, from server to client. But for passing data in the other direction, from client to server, it's better to use query parameters or a FormData
object (if your browser supports it), for example:
var data = new FormData();
data.append('user', 'person');
xhr = new XMLHttpRequest();
xhr.open('PUT' /*for example*/, URL, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(data);
Btw, I find this blog post extremely useful for designing a RESTful API:
http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api
Passing parameters to the server
It will help to explain this in the context of the example on the blog post I recommended earlier:
GET /tickets
- Retrieves a list of tickets- Query parameters are acceptable to adjust the formatting and output fields
- The most important "input" is the URL component
/tickets
GET /tickets/12
- Retrieves a specific ticket- Query parameters are acceptable to adjust the formatting and output fields
- The most important "input" is the URL component
/tickets/12
POST /tickets
- Creates a new ticket- All parameters should be posted as form data
PUT /tickets/12
- Updates ticket #12- All parameters should be posted as form data
PATCH /tickets/12
- Partially updates ticket #12- All parameters should be posted as form data
DELETE /tickets/12
- Deletes ticket #12- No parameters
The common ways of passing data to the server:
- Query string with key-value pairs
- Form data with key-value pairs
- Cookies with key-value pairs
Basically it's always key-value pairs. You could send JSON embedded inside a value, but it's not natural. The server has to deserialize it. Given some client-side parameters as key-value pairs, why pass to the server somekey => json_encoded_blob_of_key_value_pairs
when you can pass the key-value pairs in a more direct way.
-
2\$\begingroup\$ Why is
JSON
a good format for response data but not request data? Also setting theapplication/x-www-form-urlencoded
header will havePHP
parse the input and fill it into$_POST
even if the request method is notPOST
, which is not correct. Please support your statements with arguments. \$\endgroup\$php_nub_qq– php_nub_qq2014年08月28日 08:17:31 +00:00Commented Aug 28, 2014 at 8:17
_method=delete
. \$\endgroup\$