这篇文章上次修改于 1810 天前,可能其部分内容已经发生变化,如有疑问可询问作者。

今天我大胆的开坑做起了 新个人首页 里面的图库功能,一开始可谓是非常的担心自己越搞越糟,但随着我对 PHP 的入门,并结合参考着朋友写的项目,我逐渐有了一点后端思维。在中午的时候,就把图片上传服务器的效果实现了。这个程序不需要登录直接就可以在前端提交最新信息,可谓是非常的方便~ 而这项功能的实现,就借助了我们今天所提到的主角:FormData + XHR 了。

实现思路

我使用了原生 JS 来编写前端部分,没有采用 HTML5form 标签来实现提交。因为会跳转到对应的提交地址,这不是我想要的效果,因此打算直接拿 JavaScript 去提交表单。首先我去网上搜了一波教程看了一下,发现那些教程几乎都是拿 JQuery 写的,而我并不是 JQ 派,所以打算慢慢看 MDN 动手研究,最后总结如下。

HTML

基础的表单元素还是得有的,这里我通过 input 实现内容编写和文件的选择。

<div class="paul-form">
    <input type="file" name="file" id="file">
    <textarea placeholder="内容:" id="content"></textarea>
    <button class="btn blue small" id="submit">提交</button>
</div>

JavaScript

采用 ID 的方式获取各个 input 的内容,并给提交按钮增加点击事件。

var file_input = document.getElementById("file");
var content_input = document.getElementById("content");
var submit_btn = document.getElementById("submit");

记录内容

然后给 submit_btn 加上 onclick 事件,并执行对应的处理函数。

submit_btn.onclick = function () {
    ajax_send(content_input.value, file_input.files[0]); // 内容和文件
}

function ajax_send(content, file){
    // 用于发送内容的函数
}

准备发送

如果是一个普通的字符串请求,我们可以直接在 send 方法里面组合字符串发出去(例下),而文件就不可以了。

request.send("name=" + name + "&content=" + content);

为了上传文件,我们首先需要创建一个 FormData 对象,这样就可以了!

var data = new FormData();

然后把我们的 input 内容录入到我们的 FormData 对象,分别是文件和描述内容

data.append("file", file);
data.append("content", content);

接下来就可以开始加入 XHR 来提交我们的文件和描述了。

var request = new XMLHttpRequest();
request.open("POST", "你要提交处理的地址");
request.setRequestHeader("X-Requested-With", "XMLHttpRequest"); // 设置请求类型
request.send(data); // 用 Send 方法可以发送字符串和 FormData 对象的内容

最后,我们在服务器端得到结果,进行判断和显示:

request.onreadystatechange = function () {
    if(request.readyState === 4){
        // 如果成功连接服务器
        if(request.status === 200 || request.status === 304){
            ks.notice("提交成功~");
        }
        else{
            ks.notice("提交出错了!");
        }
    }
};

PHP

在服务器端,我们可以把提交的内容进行输出和显示。

// 如果提交了文件
if($_POST["content"] && $_FILES["file"]){
    $content = $_POST["content"];
}

一旦我们提交了文件,服务器就会自动吧上传的内容放在缓存。所以需要移动一下才可以输出。

move_uploaded_file($_FILES["file"]["tmp_name"], "upload/" . time() . ".jpg");

最后输出内容:

echo $content;
echo "<img src='" . upload/ . time() . ".jpg'/>";

扩展

如果你使用 Kico Style JS,你只需要编写类似 JQ 的一个写法就可以实现快速发送内容,像这样:

ks.ajax({
    // 请求类型
    method: "GET",
    // 地址
    url: "https://api.paugram.com/netease/" + url,
    // 连接成功
    success: function (req){
        var item = JSON.parse(req.response);
        if(player_1) player_1.add([item]);
    },
    // 连接失败
    failed: function (req){
        ks.notice("连接失败!", {color: "red"});
    }
});

相关介绍请移步 Kico Style 文档