使用 AJAX 上传文件并传递额外数据:FormData 的正确用法

霞舞
发布: 2025-09-15 20:10:01
原创
490人浏览过

使用 ajax 上传文件并传递额外数据:formdata 的正确用法

本文旨在帮助开发者理解如何使用 AJAX 上传文件,并同时传递额外的参数到服务器端。重点讲解了 FormData 对象在 AJAX 文件上传中的正确使用方式,以及如何避免常见的错误配置。同时,本文也强调了服务器端代码安全的重要性,并提供了防止 SQL 注入攻击的建议。

使用 FormData 对象上传文件和传递数据

在使用 AJAX 上传文件时,FormData 对象是一个非常有用的工具。它可以方便地将文件数据和其他表单数据打包在一起,并通过 AJAX 请求发送到服务器。以下是一个基本的使用示例:

前端 (JavaScript):

var form_data = new FormData();
var files = $('#multiple_files')[0].files;

// 检查文件数量
if(files.length > 15) {
    alert('You can not select more than 15 files');
    return;
}

// 添加文件到 FormData
for(var i = 0; i < files.length; i++) {
    form_data.append("files[]", files[i]); // 使用 files[] 允许上传多个文件
}

// 添加额外的参数
var id = "<?php echo $id ?>"; // 从 PHP 获取 ID
form_data.append("id", id);

// 发送 AJAX 请求
$.ajax({
    url: "upload.php",
    data: form_data,
    method: "POST",
    contentType: false,
    cache: false,
    processData: false,
    beforeSend: function() {
        $('#error_multiple_files').html('<br /><label class="text-primary">Uploading...</label>');
    },
    success: function(data) {
        $('#error_multiple_files').html('<br /><label class="text-success">Uploaded</label>');
        load_image_data();
    },
    error: function(xhr, status, error) {
        console.error("AJAX request failed:", status, error);
        $('#error_multiple_files').html('<br /><label class="text-danger">Upload Failed</label>');
    }
});
登录后复制

关键点:

  • FormData 对象: 使用 new FormData() 创建一个 FormData 对象,用于存储要上传的数据。
  • append() 方法: 使用 form_data.append(key, value) 方法向 FormData 对象中添加数据。 key 是服务器端接收数据的键名,value 是要上传的数据。 注意,对于上传多个文件,推荐使用 files[] 作为键名,服务器端更容易处理。
  • contentType: false 和 processData: false: 这两个选项必须设置为 false,才能正确地发送 FormData 对象。 contentType: false 阻止 jQuery 设置 Content-Type 头部,让浏览器自动设置,以便包含 multipart/form-data。 processData: false 阻止 jQuery 将 FormData 对象转换为字符串。

服务器端 (PHP):

<?php

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $id = $_POST['id']; // 获取 ID

    // 检查是否有文件上传
    if (isset($_FILES['files'])) {
        $files = $_FILES['files'];
        $fileCount = count($files['name']);

        for ($i = 0; $i < $fileCount; $i++) {
            $file_name = $files['name'][$i];
            $file_tmp = $files['tmp_name'][$i];
            $file_error = $files['error'][$i];

            // 检查上传是否出错
            if ($file_error === UPLOAD_ERR_OK) {
                // 生成唯一的文件名
                $new_file_name = uniqid() . '_' . $file_name;
                $file_destination = 'uploads/' . $new_file_name;

                // 移动上传的文件
                if (move_uploaded_file($file_tmp, $file_destination)) {
                    // TODO:  使用预处理语句防止 SQL 注入
                    $query = "INSERT INTO tbl_image (postid, image_name, image_description) VALUES (?, ?, '')";
                    $stmt = $mysqli->prepare($query);
                    $stmt->bind_param("ss", $id, $new_file_name); // "ss" 表示两个字符串参数
                    $stmt->execute();
                    $stmt->close();

                    echo "File uploaded successfully: " . $file_name . "\n";
                } else {
                    echo "Failed to move uploaded file: " . $file_name . "\n";
                }
            } else {
                echo "Error uploading file: " . $file_name . " (Error code: " . $file_error . ")\n";
            }
        }
    } else {
        echo "No files uploaded.\n";
    }
} else {
    echo "Invalid request method.\n";
}

?>
登录后复制

关键点:

  • $_POST 和 $_FILES: 使用 $_POST 数组获取通过 FormData 对象传递的非文件数据,例如 id。 使用 $_FILES 数组获取上传的文件信息。
  • move_uploaded_file(): 使用 move_uploaded_file() 函数将上传的临时文件移动到指定目录。
  • 错误处理: 务必检查上传过程中可能出现的错误,并进行适当的处理。
  • 安全性: 对上传的文件进行验证,例如检查文件类型和大小,以防止恶意文件上传。

避免 SQL 注入

代码中原有的 SQL 查询存在严重的 SQL 注入漏洞。 绝对不要 直接将用户输入的数据插入到 SQL 查询语句中。 攻击者可以通过构造恶意的输入,来执行任意的 SQL 代码,从而窃取、修改或删除数据库中的数据。

AppMall应用商店
AppMall应用商店

AI应用商店,提供即时交付、按需付费的人工智能应用服务

AppMall应用商店 56
查看详情 AppMall应用商店

解决方案:使用预处理语句 (Prepared Statements)

预处理语句是一种安全的 SQL 查询方式,它可以将 SQL 查询语句和数据分离开来。 首先,定义一个包含占位符的 SQL 查询语句。 然后,将用户输入的数据绑定到占位符上。 数据库系统会自动对数据进行转义,从而防止 SQL 注入。

示例 (使用 mysqli 扩展):

<?php

// 假设你已经建立了数据库连接 $mysqli

// 准备 SQL 语句
$query = "INSERT INTO tbl_image (postid, image_name, image_description) VALUES (?, ?, '')";

// 创建预处理语句
$stmt = $mysqli->prepare($query);

// 检查预处理语句是否创建成功
if ($stmt === false) {
    die("Error preparing statement: " . $mysqli->error);
}

// 绑定参数
$stmt->bind_param("ss", $id, $new_file_name); // "ss" 表示两个字符串参数

// 执行查询
if ($stmt->execute()) {
    echo "Record inserted successfully.\n";
} else {
    echo "Error inserting record: " . $stmt->error . "\n";
}

// 关闭语句
$stmt->close();

?>
登录后复制

解释:

  • $mysqli-youjiankuohaophpcnprepare(): 准备 SQL 语句,返回一个语句对象。
  • $stmt->bind_param(): 绑定参数到预处理语句。 第一个参数是一个字符串,表示参数的类型。 s 表示字符串,i 表示整数,d 表示浮点数,b 表示 BLOB。 后面的参数是要绑定的变量。
  • $stmt->execute(): 执行预处理语句。
  • $stmt->close(): 关闭语句,释放资源。

其他建议:

  • 输入验证: 在服务器端对所有用户输入的数据进行验证,例如检查数据类型、长度和格式。
  • 最小权限原则: 数据库用户只应该拥有执行其所需操作的最小权限。
  • 定期更新: 定期更新 PHP 和 MySQL,以修复安全漏洞。

总结

本文详细介绍了如何使用 AJAX 上传文件并传递额外数据,重点强调了 FormData 对象的正确用法,以及避免 SQL 注入攻击的重要性。 通过使用 FormData 对象,可以方便地将文件数据和其他表单数据打包在一起,并通过 AJAX 请求发送到服务器。 通过使用预处理语句,可以有效地防止 SQL 注入攻击,保护数据库的安全。 务必遵循最佳实践,编写安全可靠的代码。

以上就是使用 AJAX 上传文件并传递额外数据:FormData 的正确用法的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
热门推荐
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号