最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - jQuery AJAX call returning 403 Forbidden error when passing Rgraph image data - Stack Overflow

programmeradmin0浏览0评论

I am working on a project, where I have implemented a couple of graphs/charts using the Rgraph PHP library. In my script I do the following for the graphs:

  1. Calculate the graph points and draw the graph using the Rgraph Draw() method.
  2. Create an image data variable using the canvas.toDataURL() method.
  3. Pass this image data variable to the server using jQuery AJAX $.post() method.
  4. Save the image to server via the PHP script.

Everything in this solution works great on my localhost, however on the development server, the AJAX request that passes the image data returns a 403 Error.

I logged the data on both the client and server side to determine the issue. Client side logging confirms the imageData variable being passed looks correct. However server side logging confirms that the imageData variable being passed is what is causing the issue.

There was a very similar question posted last year about this, however they were unable to determine the root cause of this. Can anyone help point me in the right direction of resolving this?

I'm thinking this is a possible data encoding issue, but if this the case, why does it work on one server and not the other?

My Relevant Javascript:

radar.Set('chart.contextmenu', [
     ['Get PNG', RGraph.showPNG],
     null,
     ['Cancel', function () {}]
]);

radar.Draw();   

var imageData = radar.canvas.toDataURL("image/png");

console.log('imageData: ' + imageData);
console.log('filename: ' + 'tmpRadar<?php echo $us['UsersSurvey']['user_id']; ?>-<?php echo $survey['Survey']['id']; ?>.png');

$.post("/Surveys/save_chart", { 
    src     : imageData, 
    filename: 'tmpRadar<?php echo $us['UsersSurvey']['user_id']; ?>-<?php echo $survey['Survey']['id']; ?>.png'
});

Client Side Logging:

imageData: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABLAAAAOECAYAAACxbcj6AAAgAElEQ…AgQIAAgVECAqxR49YsAQIECBAgQIAAAQIECBAgQKCfwP8CXHJ+WDHVMbcAAAAASUVORK5CYII=
filename: tmpRadar19-1.png
POST  403 (Forbidden)

PHP Function called by AJAX:

public function save_chart() {
    if($this->request->is('ajax')) {
        $this->log('request data: '.print_r($this->request->data, true));

        $filename = $this->request->data['filename'];

        $src     = $this->request->data['src'];
        $src     = substr($src, strpos($src, ",") + 1);
        $decoded = base64_decode($src);

        $fp = fopen(WWW_ROOT.'files/graphs/'.$filename,'wb');
        if(fwrite($fp, $decoded)) {
            fclose($fp);
            return json_encode(array('success' => '1'));
        } else {
            fclose($fp);
            return json_encode(array('success' => '0'));
        }
    }
}

I am working on a project, where I have implemented a couple of graphs/charts using the Rgraph PHP library. In my script I do the following for the graphs:

  1. Calculate the graph points and draw the graph using the Rgraph Draw() method.
  2. Create an image data variable using the canvas.toDataURL() method.
  3. Pass this image data variable to the server using jQuery AJAX $.post() method.
  4. Save the image to server via the PHP script.

Everything in this solution works great on my localhost, however on the development server, the AJAX request that passes the image data returns a 403 Error.

I logged the data on both the client and server side to determine the issue. Client side logging confirms the imageData variable being passed looks correct. However server side logging confirms that the imageData variable being passed is what is causing the issue.

There was a very similar question posted last year about this, however they were unable to determine the root cause of this. Can anyone help point me in the right direction of resolving this?

I'm thinking this is a possible data encoding issue, but if this the case, why does it work on one server and not the other?

My Relevant Javascript:

radar.Set('chart.contextmenu', [
     ['Get PNG', RGraph.showPNG],
     null,
     ['Cancel', function () {}]
]);

radar.Draw();   

var imageData = radar.canvas.toDataURL("image/png");

console.log('imageData: ' + imageData);
console.log('filename: ' + 'tmpRadar<?php echo $us['UsersSurvey']['user_id']; ?>-<?php echo $survey['Survey']['id']; ?>.png');

$.post("/Surveys/save_chart", { 
    src     : imageData, 
    filename: 'tmpRadar<?php echo $us['UsersSurvey']['user_id']; ?>-<?php echo $survey['Survey']['id']; ?>.png'
});

Client Side Logging:

imageData: data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABLAAAAOECAYAAACxbcj6AAAgAElEQ…AgQIAAgVECAqxR49YsAQIECBAgQIAAAQIECBAgQKCfwP8CXHJ+WDHVMbcAAAAASUVORK5CYII=
filename: tmpRadar19-1.png
POST http://website./Surveys/save_chart 403 (Forbidden)

PHP Function called by AJAX:

public function save_chart() {
    if($this->request->is('ajax')) {
        $this->log('request data: '.print_r($this->request->data, true));

        $filename = $this->request->data['filename'];

        $src     = $this->request->data['src'];
        $src     = substr($src, strpos($src, ",") + 1);
        $decoded = base64_decode($src);

        $fp = fopen(WWW_ROOT.'files/graphs/'.$filename,'wb');
        if(fwrite($fp, $decoded)) {
            fclose($fp);
            return json_encode(array('success' => '1'));
        } else {
            fclose($fp);
            return json_encode(array('success' => '0'));
        }
    }
}
Share Improve this question edited May 23, 2017 at 12:30 CommunityBot 11 silver badge asked May 6, 2015 at 0:27 VerySeriousSoftwareEndeavoursVerySeriousSoftwareEndeavours 1,7534 gold badges32 silver badges64 bronze badges 3
  • please show both logging client side and server side (both one that working and one that does't) – Varun Naharia Commented May 22, 2015 at 12:18
  • have you checked the apache log files ? I think they might give some insight about the problem – dav Commented May 25, 2015 at 18:38
  • Have you verified this is not a CORS issue? developer.mozilla/en-US/docs/Web/HTTP/Access_control_CORS – Byte Lab Commented May 27, 2015 at 0:39
Add a ment  | 

3 Answers 3

Reset to default 2 +50

Assuming CORS isn't the issue here (which it doesn't sound like it is given that it's working fine on your localhost and that it sounds like your POSTing to the same domain from which you received the original GET), it's likely a misconfiguration between Apache on your localhost and devbox. Given that the issue is only with your base 64 encoded image POST, it's likely too large so apache is rejecting it.

Per this SO post, try setting the following in either your php.ini:

post_max_size=20M
upload_max_filesize=20M

or in .htaccess / httpd.conf / virtualhost:

php_value post_max_size 20M
php_value upload_max_filesize=20M

Note that I can't tell you for sure if this is the cause until you post the apache error log.

It’s to do with mod_security (an Apache module) and the http:// part of the URL.

You have two options here,

  • Modify the Apache module
  • Client side workaround

Try removing imagedata from the form you are posting, and it should submit.

Source: 403-on-form-submit

Your use of data in .post() is a little off. If you are trying to pass a JSON object as the data for the second argument of .post(), you need to properly form it into a JSON string. Try wrapping your dictionary with JSON.stringify(). It'll take your javascript value {key1: value1, key2: value2} and format it.

https://developer.mozilla/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify

$.post("/Surveys/save_chart", JSON.stringify(
  { 
    src     : imageData, 
    filename: 'tmpRadar<?php echo $us['UsersSurvey']['user_id']; ?>-<?php echo $survey['Survey']['id']; ?>.png'
  }
) //end stringify 
)//end post;
发布评论

评论列表(0)

  1. 暂无评论