doumeikuan6834 2013-01-01 00:59
浏览 63
已采纳

使用Ajax的JQuery POST覆盖txt文件无法正常工作

I have a site http://www.gfcf14greendream.com/ where I'm posting my programs and games. I have no problem writing code to download a program I made (click on the Programs button then SMS Sender), but I'm rather confused as to how to generate a counter. Before anything, I do not wish to use one from a website, because I'd really like to format it myself. The way I thought of doing this was through the use of a txt file, smssender.txt which simply has:

0

Then the javascript of the site which handles the overwrite of the txt file is:

$("#downbutton").click(function () {
    downcounter++;
    if (downcounter == 1) $("#counter").text("SMS Sender has been downloaded " + downcounter + " time...");
    else $("#counter").text("SMS Sender has been downloaded " + downcounter + " times...");
    $.post("http://www.gfcf14greendream.com/PHP/smssender.php", {
        counter: downcounter
    }, function (data) {});
});

which should call a PHP file, smssender.php, which has but 5 lines:

<?php
    $counter = $_POST['counter'];
    file_put_contents("/counters/smssender.txt", $counter);
?>

I wish I knew if the php page is being called at all, because the code that changes the text that indicates the download times in the page works well, but as soon as the page is refreshed, the number of downloads goes back to 0, because the 0 is obtained from this code:

var downcounter = 0;
$.get("http://www.gfcf14greendream.com/counters/smssender.txt", function (data) {
    downcounter = data;
    if (downcounter == 1) $("#counter").text("SMS Sender has been downloaded " + downcounter + " time...");
    else $("#counter").text("SMS Sender has been downloaded " + downcounter + " times...");
});

which clearly indicates no overwrite took place since it successfully retrieves the 0 from smssender.txt (I've previously tried with 1 and 2 and it worked). So why is the code wrong? Any kind of help is truly appreciated. Thanks for your time, and Happy New Year to all!!

Update:

I tried changing the code of the javascript function to:

var txtfile = "http://www.gfcf14greendream.com/counters/smssender.txt";

            $.ajax({
                type:'POST',
                url: 'PHP/increment.php',
                data: txtfile,
                success: function() {
                    alert("Download incremented");
                    $.get("http://www.gfcf14greendream.com/counters/smssender.txt", function(data){
                        downcounter = data;
                        if (downcounter == 1)   $("#counter").text("SMS Sender has been downloaded " + downcounter + " time...");   
                        else $("#counter").text("SMS Sender has been downloaded " + downcounter + " times..."); 
                    });
                }               
            });

And added a PHP file, increment.php, which has some of the code you gave me here:

<? php
    $file = $_POST['txtfile'];
    $counter = intval(file_get_contents($file));
    $counter++;
    file_put_contents($file, $counter);
?>

But still, no luck. Would this code work at all or am I misusing references? Thank you

  • 写回答

1条回答 默认 最新

  • duanou9739 2013-01-01 01:14
    关注

    This is a simple method of building a counter, but there are a few problems with it.1

    Instead of relying on the client's JavaScript to supply the value to counter, it should be handled entirely on the server side. If 2 users have the page open simultaneously for example, both would start with the same value, but only increment it by one rather than properly incrementing by one each.

    This method also avoids the need to sanitize a counter value sent by the client and saved in your file, and avoids the need to process any post at all. Instead, simply calling the script can increment your counter.

    Counter PHP script

    // Does nothing but read and increment the file:
    // Read the value
    $current_counter = intval(file_get_contents('/path/outside/web/root/counters/smssender.txt'));
    // Increment it
    $current_counter++;
    file_put_contents('/path/outside/web/root/counters/smssender.txt', $current_counter);
    // Output it to the client
    echo $current_counter;
    

    The JavaScript's responsibility is then only to call the PHP script, with no parameters.

    $.get("http://www.gfcf14greendream.com/PHP/smssender.php", function(data) {
      // Do something on success
      console.log(data);
    });
    

    To protect against direct requests of the smssender.txt file, it is recommended to store that file outside the web server document root. Supply the correct path to the file in file_get_contents()/file_put_contents().

    To retrieve the current counter value and send it to the client you just need to read and echo the value.

    echo intval(file_get_contents('/path/outside/web/root/counters/smssender.txt'));
    

    Finally, be aware that there's nothing here to prevent anyone from running up your counter by just calling the smssender.php script over and over. If you have a login, you should make sure users are signed in when accessing the counter. Absent a login, you should consider setting a cookie value when the download actually occurs, so you can assert that the user has actually downloaded something in the current session when the counter is incremented.

    if (isset($_COOKIE['some-download-value'])) {
      // Update the counter.
    }
    

    Addendum:

    If your web host does not permit you to place files outside the web server document root, you can block direct HTTP requests to the .txt file with a rule like the following in your .htaccess:

    # Block direct access to any .txt file
    <Files ~ "\.txt$">
      order allow,deny
      deny from all
    </Files>
    

    Or you could place the following in a .htaccess file inside the counters/ directory:

    # counters/.htaccess
    # block all HTTP requests to counter files
    Order deny,allow
    Deny from all
    

    1 A simpler method, which avoids all the file storage, reading, writing, and security issues is to store the counter value in a database table and UPDATE it on each access.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?