我想用jQuery异步上传文件。

$(文档).ready(函数(){$(“#uploadbutton”).click(函数(){var filename=$(“#file”).val();$.ajax美元({类型:“POST”,url:“addFile.do”,enctype:'多部分/表单数据',数据:{文件:文件名},成功:函数(){alert(“上传的数据:”);}});});});<script src=“https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js“></script><span>文件</span><input type=“file”id=“file”name=“file”size=“10”/><input id=“uploadbutton”type=“button”value=“Upload”/>

我只得到文件名,而不是上传文件。我可以做什么来解决这个问题?


当前回答

对于PHP,请查找https://developer.hyvor.com/php/image-upload-ajax-php-mysql

HTML

<html>
<head>
    <title>Image Upload with AJAX, PHP and MYSQL</title>
</head>
<body>
<form onsubmit="submitForm(event);">
    <input type="file" name="image" id="image-selecter" accept="image/*">
    <input type="submit" name="submit" value="Upload Image">
</form>
<div id="uploading-text" style="display:none;">Uploading...</div>
<img id="preview">
</body>
</html>

JAVASCRIPT语言

var previewImage = document.getElementById("preview"),  
    uploadingText = document.getElementById("uploading-text");

function submitForm(event) {
    // prevent default form submission
    event.preventDefault();
    uploadImage();
}

function uploadImage() {
    var imageSelecter = document.getElementById("image-selecter"),
        file = imageSelecter.files[0];
    if (!file) 
        return alert("Please select a file");
    // clear the previous image
    previewImage.removeAttribute("src");
    // show uploading text
    uploadingText.style.display = "block";
    // create form data and append the file
    var formData = new FormData();
    formData.append("image", file);
    // do the ajax part
    var ajax = new XMLHttpRequest();
    ajax.onreadystatechange = function() {
        if (this.readyState === 4 && this.status === 200) {
            var json = JSON.parse(this.responseText);
            if (!json || json.status !== true) 
                return uploadError(json.error);

            showImage(json.url);
        }
    }
    ajax.open("POST", "upload.php", true);
    ajax.send(formData); // send the form data
}

PHP

<?php
$host = 'localhost';
$user = 'user';
$password = 'password';
$database = 'database';
$mysqli = new mysqli($host, $user, $password, $database);


 try {
    if (empty($_FILES['image'])) {
        throw new Exception('Image file is missing');
    }
    $image = $_FILES['image'];
    // check INI error
    if ($image['error'] !== 0) {
        if ($image['error'] === 1) 
            throw new Exception('Max upload size exceeded');

        throw new Exception('Image uploading error: INI Error');
    }
    // check if the file exists
    if (!file_exists($image['tmp_name']))
        throw new Exception('Image file is missing in the server');
    $maxFileSize = 2 * 10e6; // in bytes
    if ($image['size'] > $maxFileSize)
        throw new Exception('Max size limit exceeded'); 
    // check if uploaded file is an image
    $imageData = getimagesize($image['tmp_name']);
    if (!$imageData) 
        throw new Exception('Invalid image');
    $mimeType = $imageData['mime'];
    // validate mime type
    $allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif'];
    if (!in_array($mimeType, $allowedMimeTypes)) 
        throw new Exception('Only JPEG, PNG and GIFs are allowed');

    // nice! it's a valid image
    // get file extension (ex: jpg, png) not (.jpg)
    $fileExtention = strtolower(pathinfo($image['name'] ,PATHINFO_EXTENSION));
    // create random name for your image
    $fileName = round(microtime(true)) . mt_rand() . '.' . $fileExtention; // anyfilename.jpg
    // Create the path starting from DOCUMENT ROOT of your website
    $path = '/examples/image-upload/images/' . $fileName;
    // file path in the computer - where to save it 
    $destination = $_SERVER['DOCUMENT_ROOT'] . $path;

    if (!move_uploaded_file($image['tmp_name'], $destination))
        throw new Exception('Error in moving the uploaded file');

    // create the url
    $protocol = stripos($_SERVER['SERVER_PROTOCOL'],'https') === true ? 'https://' : 'http://';
    $domain = $protocol . $_SERVER['SERVER_NAME'];
    $url = $domain . $path;
    $stmt = $mysqli -> prepare('INSERT INTO image_uploads (url) VALUES (?)');
    if (
        $stmt &&
        $stmt -> bind_param('s', $url) &&
        $stmt -> execute()
    ) {
        exit(
            json_encode(
                array(
                    'status' => true,
                    'url' => $url
                )
            )
        );
    } else 
        throw new Exception('Error in saving into the database');

} catch (Exception $e) {
    exit(json_encode(
        array (
            'status' => false,
            'error' => $e -> getMessage()
        )
    ));
}

其他回答

您可以通过JavaScript使用更新的Fetch API。这样地:

function uploadButtonCLicked(){
    var input = document.querySelector('input[type="file"]')

    fetch('/url', {
      method: 'POST',
      body: input.files[0]
    }).then(res => res.json())   // you can do something with response
      .catch(error => console.error('Error:', error))
      .then(response => console.log('Success:', response));
}                               

优点:所有现代浏览器都支持Fetch API,因此您不必导入任何内容。此外,请注意,fetch()返回Promise,然后使用.then(..代码处理响应..)异步处理Promise。

你也可以考虑使用类似的https://uppy.io.

它可以在不离开页面的情况下进行文件上传,并提供一些奖励,如拖放、在浏览器崩溃/网络不稳定的情况下恢复上传,以及从例如Instagram导入。它是开源的,不依赖于jQuery/React/Angular/Vue,但可以与它一起使用。免责声明:作为它的创建者,我有偏见;)

这是我的解决方案。

<form enctype="multipart/form-data">    

    <div class="form-group">
        <label class="control-label col-md-2" for="apta_Description">Description</label>
        <div class="col-md-10">
            <input class="form-control text-box single-line" id="apta_Description" name="apta_Description" type="text" value="">
        </div>
    </div>

    <input name="file" type="file" />
    <input type="button" value="Upload" />
</form>

和js

<script>

    $(':button').click(function () {
        var formData = new FormData($('form')[0]);
        $.ajax({
            url: '@Url.Action("Save", "Home")',  
            type: 'POST',                
            success: completeHandler,
            data: formData,
            cache: false,
            contentType: false,
            processData: false
        });
    });    

    function completeHandler() {
        alert(":)");
    }    
</script>

控制器

[HttpPost]
public ActionResult Save(string apta_Description, HttpPostedFileBase file)
{
    [...]
}

Try

异步函数saveFile(){let formData=新formData();formData.append(“file”,file.files[0]);wait-fetch('addFile.do',{method:“POST”,body:formData});alert(“上传的数据:”);}<span>文件</span><input type=“file”id=“file”name=“file”size=“10”/><input type=“button”value=“Upload”onclick=“saveFile()”/>

content-type='multipart/form-data'由浏览器自动设置,文件名也自动添加到文件名FormData参数中(服务器可以轻松读取)。下面是一个更为成熟的错误处理和json添加示例

异步函数saveFile(inp){让用户={name:'john',年龄:34};let formData=新formData();let photo=inp.files[0];formData.append(“照片”,照片);formData.append(“用户”,JSON.stringify(用户));尝试{let r=等待获取('/upload/image',{method:“POST”,body:formData});console.log('HTTP响应代码:',r.status);警报(“成功”);}捕获(e){console.log('休斯顿我们有问题…:',e);}}<input-type=“file”onchange=“saveFile(this)”><br><br>在选择文件之前,打开chrome控制台>网络选项卡以查看请求详细信息。<br><br><small>因为在本例中,我们将请求发送到https://stacksnippets.net/upload/image响应代码当然是404</小>

如果使用承诺使用哪种ajax,并检查文件是否有效并保存在后端,那么您可以在用户浏览页面时在前面使用一些动画。

您甚至可以使用递归方法使其并行上传或堆叠