Vineet Sharma
Vineet Sharma

Reputation: 221

How to choose the right dataType and contentType value for AJAX request?

I have written some jQuery + PHP code that takes the HTML from an element on a webpage and saves it on server. Here is the code that I am using:

var page = {
    'html': document.querySelector("article").innerHTML,
    'url': 'path/current/webpage.php' or (<?php echo "'$current_page'"; ?>) 
    // Both give same 'url' value. This is not an issue. 
};

$.ajax({
    url:'https://example.com/update.php',
    type:'post',
    data: page,
    success:function(data){
        window.location.reload();
    }
});

Here is my code for update.php:

$content = $_REQUEST['html'];
$page = $_REQUEST['url'];
file_put_contents($page, $content, LOCK_EX);

I am not very comfortable with dataType and contentType so I skipped them initially. However the request succeeded sometimes but gave 403() error other times.I did a little research and found that this might be due to lack of dataType and contentType. So, I used the following values:

contentType: 'text/plain; charset=utf-8',
dataType: 'html'

I no longer get any errors but the pages are not actually updating. I also tried setting the values to:

contentType:'application/json',
dataType: 'html'

This time too, I did not get any 403() errors but the page would not actually update.

Does the post data needs to be accessed differently based on the value of contentType like 'application/json' or 'text/plain; charset=utf-8'? Because the updates don't seem to show up on the webpage even with a 200 response code.

Using application/x-www-form-urlencoded; charset=UTF-8 updates some pages but gives 403() error for others.

Upvotes: 0

Views: 1706

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1073968

As Rory said (as did I, in an answer I wrote then deleted when I saw his comment; he was right to comment instead), a 403 response code probably doesn't mean there's a problem with either dataType or contentType. You should look for other reasons the server would refuse to satisfy the request. For instance, as you're posting HTML, perhaps you (or your web host) has some kind of anti-script-injection protection going on. You'll have to track that down, perhaps with your hosting company.

But two things: Some info for completeness, and a potential workaround:

dataType is the type you expect back from the server. contentType is the type of data you're sending to the server.

For the request you're sending, leaving off contentType is correct, because the default jQuery will use is what PHP will expect to see.

You shouldn't have to specify dataType at all; instead, you should ensure the response carries the correct Content-Type header. That means ensuring that your server is configured correctly (for static content) and that your PHP code sets the correct header if necessary via header("Content-Type: data/type-here") The only reason for specifying dataType is if you don't control the server and you know it sends back the wrong type.

If you need to try to work around it, first ask: What if someone sends me malicious HTML directly, not through my web page? The answer is: You need to be careful with what you do with the HTML. For example: If you are going to store this HTML and then display it (as HTML) to a user, that's a Cross-Site Scripting vulnerability and you have to rigorously sanitize that HTML before doing that.

Do not proceed with any workaround until you've answered that question for yourself.

Okay, so in terms of working around it (once you have robust safeguards in place): You might send JSON rather than a standard form, in hopes that whatever is rejecting the forms won't look at it. To do that, you'd change your ajax call:

var page = {
    html: document.querySelector("article").innerHTML,
    url: <?php echo "'$current_page'"; ?>
};
$.ajax({
    url:'https://example.com/update.php',
    type:'post',
    data: JSON.stringify(page),
    contentType: 'application/json; charset=UTF8',
    success:function(data){
        window.location.reload();
    }
});

Then on the PHP side, you'd read that JSON and parse it (reading code below taken from this answer):

$entityBody = json_decode(stream_get_contents(STDIN));
$content = $entityBody['html'];
$page = $entityBody['url'];
file_put_contents($page, $content, LOCK_EX);

Again: Please do not use this unless you have robust anti-XSS safeguards in place. And again, if you do haev robust anti-XSS safeguards in place, you might be able to just use a normal form by changing your server config.

Upvotes: 1

Related Questions