Ajax XMLhttprequest Post 到 PHP 脚本和旋转图像

Ajax XMLhttprequest Post to PHP script and Rotate Image

我知道我哪里有大问题,但我似乎无法解决它们。我正在尝试通过 Ajax 使用 PHP 旋转图像。我只想在每次按下按钮时将图像旋转 90 度。有人可以帮忙吗?我知道我正在告诉我的 PHP 脚本检索 $_POST['image'] 变量,但我没有发送一个,这就是我收到 php 错误的原因。我知道 php 脚本有效。我不知道我是否可以在我的脚本中使用 xhttp.open("GET") 。我知道我的 html 和重新加载标签中的图像还有其他问题。非常感谢任何帮助。

这是我的 JS:

<script>

function rotateImage(){
var xhttp = new XMLHttpRequest();   
xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        document.getElementById("rotate").innerHTML =   this.responseText;
   }
};

xhttp.open("POST", "rotate.php", true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
xhttp.send("<?php echo $fileName; ?>");
}
</script>

这是我的 PHP:

<?php 
    
    $image = $_POST['image'];
    $degree = 90;
    $source = imagecreatefromjpeg($image);
    // Rotate
    $rotate = imagerotate($source, $degree, 0);
    $image = imagejpeg($rotate, realpath($image), 100);
    //echo $image;
    imagedestroy($source);
    imagedestroy($rotate);

?>

还有我的HTML:

<div class="row justify-content-center mb-3">
    <div class="col-lg col-auto">
    <?php list($width, $height) = getimagesize($fileName); ?>     
        <div class="mb-1" id="rotate"><img class="rounded img-fluid" src="<?php echo $fileName; ?>" alt="Your Profile Photo" width="<?php echo $width; ?>" height="<?php echo $height; ?>" /></div>
        <div class="text-center"><button onClick="rotateImage()" class="btn btn-outline-primary btn-sm"><i class="fas fa-sync-alt"></i> Rotate</button></div>
  </div>

在这个问题中,不知道最初声明的 $filename 是在哪里以及如何派生的,或者特定的文件夹结构/服务器配置是什么,所以以下可能需要调整以适应您的环境,因为我的测试站点使用别名文件夹超出站点根目录...无论如何 - 使用 Ajax(或此处的 Fetch api)将 filename/filepath 发送到 PHP 很容易。 PHP 脚本做了它应该做的,除了它没有 return 一个值,但是当 ajax 请求完成时强制浏览器 "reload" 图像的技巧是附加缓存破坏时间戳。

据说可以在 Fetch 请求上设置的 cache:'reload' 属性 将确保图像不被缓存,但我发现这在这种情况下没有效果。

<?php
    if( $_SERVER['REQUEST_METHOD']=='POST' && isset( 
        $_POST['filename'],
        $_POST['path'],
        $_POST['dir']
    )){
        ####################
        # emulate rotate.php
        ####################
        ob_clean();
        
        $image = sprintf('%s/%s', $_POST['path'], basename( $_POST['filename'] ) );
        $angle = $_POST['dir']=='clockwise' ? -90 : 90;
        
        $source = imagecreatefromjpeg( $image );
        imagesetinterpolation( $source, IMG_MITCHELL );
        
        $rotate = imagerotate( $source, $angle, 0 );
        imagejpeg( $rotate, realpath( $image ), 100 );

        imagedestroy( $source );
        imagedestroy( $rotate );
        
        list( $width, $height, $type, $attr ) = getimagesize( $image );
        
        $args=array(
            'filename'  =>  $_POST['filename'],
            'width'     =>  $width,
            'height'    =>  $height
        );
        
        
        header('Content-Type: application/json');
        exit( json_encode( $args ) );
    }
?>
<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title></title>
    </head>
    <body>
    
        <div class='row justify-content-center mb-3'>
            <div class='col-lg col-auto'>
                <?php
                
                    /*
                        $path here will be the full path and $filename
                        contains the web accessible path. As mentioned
                        my setup is complicated and relies upon aliased
                        folders outside site root.
                    */
                    $path=realpath( sprintf('%s/images/uploads', getcwd() ) );
                    $filename='images/uploads/abronsius.jpg';
                ?>     
                <div class='mb-1' id='rotate'>
                    <img class='rounded img-fluid' data-path='<?php echo $path;?>' src='<?php echo $filename; ?>' alt='Your Profile Photo' />
                </div>
                
                <div class='text-center'>
                    <button class='btn btn-outline-primary btn-sm' data-dir='clockwise'>
                        <i class='fas fa-sync-alt'></i>Rotate Clockwise
                    </button>
                    
                    <button class='btn btn-outline-primary btn-sm' data-dir='anticlockwise'>
                        <i class='fas fa-sync-alt'></i>Rotate Anti-Clockwise
                    </button>
                </div>
            </div>
        </div>
        
        
        
        <script>
            (function(){
                
                const d=document;
                const q=(e,n=d)=>n.querySelector(e);
                const qa=(e,n=d)=>n.querySelectorAll(e);
                
                qa('button.btn').forEach( bttn=>bttn.addEventListener('click',e=>{
                    let img=q('img.img-fluid');
                    
                    /* set the payload to send in the request */
                    let fd=new FormData();
                        fd.set('filename', img.src.split('?')[0] );
                        fd.set('path', img.dataset.path );
                        fd.set('dir', e.target.dataset.dir );
                    
                    let url=location.href;  //rotate.php
                    
                    /* set the request parameters */
                    let args={
                        body:fd,
                        mode:'same-origin',
                        method:'post',
                        cache:'reload', //no discernible effect
                        credentials:'same-origin'
                    };
                    /* create the request */
                    let oReq=new Request( url, args );
                    
                    /* send the request and process the response by reloading the image */
                    fetch( oReq )
                        .then( r=>r.json() )
                        .then( json=>{
                            img.src=json.filename +'?t='+( new Date() ).getTime();
                            img.width=json.width;
                            img.height=json.height;
                        })
                        .catch( err=>console.log(err) );
                }));
            })();
        </script>
    </body>
</html>