Ajax 文件负载未到达 php

问题描述 投票:0回答:1

我正在尝试解决 ajax 过程中的问题,并且已回到基础知识。

我试图通过 ajax 将画布的 blob 内容发送到某个 php,但是当我尝试包含文件或 blob 时,我在 php 端得到“没有看到任何内容”,即使我看到一个 devtools 有效负载指示项目是已发送。

php 很简单:

<?php

if ( $_SERVER['REQUEST_METHOD']=='POST' ) {
    $posts = "";

    foreach ($_GET as $k => $v) $posts .= "<LI>(get) ".($k?$k:"null")."=[".($v?$v:"null")."]</LI>";
    foreach ($_POST as $k => $v) $posts .= "<LI>(post) ".($k?$k:"null")."=[".($v?$v:"null")."]</LI>";
    foreach ($_FILES as $k => $v) $posts .= "<LI>(file) ".($k?$k:"null")."</LI>";

    if( $posts !== "" ) {
        echo "<HR>PHP processing:<LI>$posts</LI>";
        exit;
    }
    else echo "<HR>PHP processing:<LI>No post values detected</LI>";
    exit;
}
?>

随之而来的 html 是:

    const _AJAX_STATUS_OK=200;
    //----------------------------------------------------------------------------------
    function decodeEntities(html) {
        var textarea = document.createElement("textarea");
        textarea.innerHTML = html;
        return textarea.value;
    }
    function getScriptName(exQ, exH, fullPath) {
        if ( exQ==undefined ) exQ=true;
        if ( exH==undefined ) exH=true;
        if ( fullPath==undefined ) fullPath=true;
        let result=location.href;
        if ( exQ && result.indexOf('?')>0 ) result=result.substring(0,result.indexOf('?'));
        if ( exH && result.indexOf('#')>0 ) result=result.substring(0,result.indexOf('#'));
        if ( ! fullPath ) {
            result=result.substring(result.lastIndexOf('/'));
        }
        return result;
    }
    function ajax(queryParams, destEl, formData, appendFg, url, postMethod) {
        let dp;
        let xhr;
        let ap = appendFg;

        if ( postMethod==undefined ) postMethod='POST';
        if ( formData==undefined ) formData=new FormData();
        if ( destEl ) dp = destEl;
        if ( url==undefined ) url = getScriptName(true, true, true);

        if (window.XMLHttpRequest) xhr = new XMLHttpRequest();
        else if (window.ActiveXObject) xhr = new ActiveXObject('Microsoft.XMLHTTP');
        else {
            console.error("Your browser does not support Ajax");
            return;
        }

        if (postMethod.toUpperCase() === 'GET') {
            url = `${url}?${queryParams}`;
        }
        else if (postMethod.toUpperCase() === 'POST') {
            const queryParamsEntries = new URLSearchParams(queryParams).entries();
            for (const [key, value] of queryParamsEntries) {
                console.log(`Appending ... ${key}=[${value}]`);
                formData.append(key, value);
            }
            for (let [key, value] of formData.entries()) console.log('(pre-send) Resulting form key',key, value);
        }
        else {
            console.error("Invalid action type. Use 'GET' or 'POST'.");
            return;
        }

        let asyn=true;
        xhr.open(postMethod, url, asyn);

        xhr.onreadystatechange = function () {
            if (xhr.readyState === XMLHttpRequest.DONE) {
                if (xhr.status == _AJAX_STATUS_OK) {
                    if (xhr.responseText.indexOf('Fatal error') > -1 && doErrorAlerts) alert('process request err:' + xhr.responseText);
                    let update= new Array();
                    let respTxt= xhr.responseText;
                    respTxt = respTxt.replace(/{{BR}}/g, '\n');
                    respTxt = decodeEntities(respTxt);

                    if (dp) {
                        if ( ap ) dp.innerHTML += respTxt;
                        else dp.innerHTML = respTxt;
                    }
                    else {
                        console.debug('xhr result',respTxt);
                        console.log('xhr result',respTxt);
                        document.querySelector('#result').innerHTML+='<HR>Done (see console)';
                    }

                }
            }
        };

        if (postMethod.toUpperCase() === 'POST' && formData) {
            if ( queryParams ) document.querySelector('#result').innerHTML+=`<LI>Sending queryParams:${queryParams}`;
            for (let [key, value] of formData.entries()) {
                document.querySelector('#result').innerHTML+=`<LI>Sending formData(${key})=${value}`;
            }
            xhr.send(formData);
        }
        else {
            xhr.send();
        }
    }
    // ----------------------------------------------------------
    function doTest1() {
        document.querySelector('#result').innerHTML='';
        ajax("test=1&a=10&b=11", document.getElementById("result"));
    }
    function doTest2() {
        document.querySelector('#result').innerHTML='';
        var formData = new FormData();
        formData.append('test', '2');
        formData.append('a', '1');
        formData.append('b', '2');
        formData.append('c', '3');
        formData.append('d', document.querySelector(`input[type='file']`).files[0]);

        ajax(null, document.getElementById("result"), formData, true);
    }
    function doTest3a() {
        document.querySelector('#result').innerHTML='';
        doTestX('test=3&a=101', undefined, false);
    }
    function doTest3b() {
        document.querySelector('#result').innerHTML='';
        doTestX('test=4&a=102', document.getElementById("result"), false);
    }
    function doTest4a() {
        document.querySelector('#result').innerHTML='';
        doTestX('test=4&a=102', undefined, true);
    }
    function doTest4b() {
        document.querySelector('#result').innerHTML='';
        doTestX('test=4&a=102', document.getElementById("result"), true);
    }
    function doTestX(args, out, includeFile) {
        const formData = new FormData();
        if ( includeFile ) {
            let img = document.querySelector('img');
            let ft  = 'png';

            let canvas    = document.createElement('canvas');
            let ctx       = canvas.getContext('2d');
            canvas.width  = img.naturalWidth;
            canvas.height = img.naturalHeight;
            ctx.drawImage(img, 0, 0);

            const dataUrl      = canvas.toDataURL();
            const base64Data   = dataUrl.split(',')[1];
            const binaryString = atob(base64Data);
            const uint8Array   = new Uint8Array(binaryString.length);
            for (let i = 0; i < binaryString.length; i++) {
                uint8Array[i] = binaryString.charCodeAt(i);
            }
            const blob = new Blob([uint8Array], {type: 'image/' + ft});

            formData.append('file', blob, 'canvas.' + ft);
        }
        ajax(args, out, formData, true);
    }
    function canvasToFile(canvas, fileName, mimeType) {
        return new Promise((resolve, reject) => {
            canvas.toBlob(function(blob) {
                let file = new File([blob], fileName, { type: mimeType });
                resolve(file);
            }, mimeType);
        });
    }
    window.addEventListener('load', async function(event) {
        event.preventDefault();
        let img = document.querySelector('img');
        let ft  = 'png';

        let canvas    = document.createElement('canvas');
        let ctx       = canvas.getContext('2d');
        canvas.width  = img.naturalWidth;
        canvas.height = img.naturalHeight;
        ctx.drawImage(img, 0, 0);
        document.body.appendChild(canvas);

        let file         = await canvasToFile(canvas, 'canvasImage.'+ft, 'image/'+ft);
        let dataTransfer = new DataTransfer();
        dataTransfer.items.add(file);
        let fileInput   = document.getElementById('myfile');
        fileInput.files = dataTransfer.files;
    });
#result {
            background-color: #d5d5d5;
            padding:10px;
        }
        button {
            margin:8px;
        }
        canvas {
            width:25vw;
        }
        iframe {
            border:none;
            background-color:lightgrey;
        }
Testing Ajax
<br>
<br>

<img style='width:50vw' src='/images/test-image.jpg'>
<br>
<br>
<form method="POST" target="resultFrame">
    <input type="hidden" name="a" value="2001">
    <input type="file" name="myfile" id="myfile" style="xdisplay:none">
    <button>Submit form</button>
</form>
<div class="buttons">
    <button onClick="doTest1()">Go1</button>
    <button onClick="doTest2()">Go2 (with file)</button>
    <br>
    <button onClick="doTest3a()">Go3 ( /console)</button>
    <button onClick="doTest3b()">Go3 ( /screen)</button>
    <br>
    <button onClick="doTest4a()">Go4 (with img /console)</button>
    <button onClick="doTest4b()">Go4 (with img /screen)</button>
</div>
<pre id="result"></pre>
<iframe name="resultFrame"></iframe>

完整的代码可以在https://onlinephp.io/c/4677a上看到(但由于某种原因它无法运行)

如果我运行按钮 Go1,我会看到参数到达 php 并显示在灰色区域中。 如果我运行按钮 Go2 (带有文件),我会看到 formData 已建立 - 但 php 没有看到任何帖子。 我在 Go3 中进行了进一步的测试,它没有文件并且工作正常。 然后你有 Go4,它尝试包含一个文件,但像 Go2 一样,失败了。

我可以在开发工具有效负载中看到发送了一个文件、一个测试和一个 a(尽管在有效负载选项卡出现之前有可疑的延迟) - 但 php 没有看到/反映这些 enter image description here

我在这里做错了什么?

javascript php ajax
1个回答
0
投票

文件可以通过自己的数组访问

$_FILES

© www.soinside.com 2019 - 2024. All rights reserved.