uniquejava / blog

My notes regarding the vibrating frontend :boom and the plain old java :rofl.
Creative Commons Zero v1.0 Universal
11 stars 5 forks source link

ajax file upload #12

Open uniquejava opened 8 years ago

uniquejava commented 8 years ago

jQuery

http://stackoverflow.com/questions/166221/how-can-i-upload-files-asynchronously?rq=1#

<input id="file" type="file" name="file"/>
<div id="response"></div>
jQuery('document').ready(function(){
    var input = document.getElementById("file");
    var formdata = false;
    if (window.FormData) {
        formdata = new FormData();
    }
    input.addEventListener("change", function (evt) {
        var i = 0, len = this.files.length, img, reader, file;

        for ( ; i < len; i++ ) {
            file = this.files[i];

            if (!!file.type.match(/image.*/)) {
                if ( window.FileReader ) {
                    reader = new FileReader();
                    reader.onloadend = function (e) {
                        //showUploadedItem(e.target.result, file.fileName);
                    };
                    reader.readAsDataURL(file);
                }

                if (formdata) {
                    formdata.append("image", file);
                    formdata.append("extra",'extra-data');
                }

                if (formdata) {
                    jQuery('div#response').html('<br /><img src="ajax-loader.gif"/>');

                    jQuery.ajax({
                        url: "upload.php",
                        type: "POST",
                        data: formdata,
                        processData: false,
                        contentType: false,
                        success: function (res) {
                         jQuery('div#response').html("Successfully uploaded");
                        }
                    });
                }
            }
            else
            {
                alert('Not a vaild image!');
            }
        }

    }, false);
});

Explanation I use response div to show the uploading animation and response after upload is done.

Best part is you can send extra data such as ids & etc with the file when you use this script. I have mention it extra-data as in the script.

At the PHP level this will work as normal file upload. extra-data can be retrieved as $_POST data.

Here you are not using a plugin and stuff. You can change the code as you want. You are not blindly coding here. This is the core functionality of any jQuery file upload. Actually Javascript.

uniquejava commented 8 years ago

服务端(servlet3.x)

protected void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
    JSONObject result = new JSONObject();
    result.put("ok", false);
    // Retrieves <input type="text" name="username">
    String id = request.getParameter("username");
    String sex = request.getParameter("sex");
    String bio = request.getParameter("bio");

    if (id == null || id.trim().isEmpty()) {
        result.put("msg", "invalid parameter");

    } else {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            // Retrieves <input type="file" name="file">
            Part filePart = request.getPart("image");
            String fileName = filePart.getSubmittedFileName();
            InputStream fileContent = filePart.getInputStream();

            ByteArrayOutputStream buffer = new ByteArrayOutputStream();

            int nRead;
            byte[] data = new byte[16384];

            while ((nRead = fileContent.read(data, 0, data.length)) != -1) {
                buffer.write(data, 0, nRead);
            }
            buffer.flush();

            byte[] bytes = buffer.toByteArray();

            conn = getConnection();

            pstmt = conn.prepareStatement("update users set avatar=?, sex=?, bio=? where username = ?");
            pstmt.setBytes(1, bytes);
            pstmt.setString(2, sex);
            pstmt.setString(3, bio);
            pstmt.setString(4, id);
            int rows = pstmt.executeUpdate();

            result.put("ok", true);
            result.put("msg", String.valueOf(rows));
        } catch (Exception e) {
            e.printStackTrace();
            result.put("msg", "Error get profile:" + e.getMessage());

        } finally {
            cleanup(conn, pstmt, rs);
        }

        renderJson(response, result);
    }

}
uniquejava commented 8 years ago

nodejs服务端

https://github.com/expressjs/multer

var multer  = require('multer');
var storage = multer.diskStorage({
    destination: function (req, file, cb) {
        cb(null, './public/images/avatar')
    },
    filename: function (req, file, cb) {
        console.log('file is ' + file);
        cb(null, req.session.user.uuid + '.jpg');
    }
});
var upload = multer({storage: storage}).single('file');

app.post('/upload', function (req, res, next) {
    upload(req, res, function (err) {
        if (err) {
            // An error occurred when uploading
            console.log(err);
            return;
        }

        console.log(req.file);

        // Everything went fine
        var start = "images".length;
        var filePath = req.file.path.slice(start);
        res.json({hash: filePath, key: filePath});

    });
});
uniquejava commented 8 years ago

http://www.ruanyifeng.com/blog/2012/09/xmlhttprequest_level_2.html

Building a File Uploader with NodeJs

FormData详解

var formData = new FormData();

formData.append("username", "Groucho");
formData.append("accountnum", 123456); // number 123456 is immediately converted to a string "123456"

// HTML file input, chosen by user
formData.append("userfile", fileInputElement.files[0]);

// JavaScript file-like object
var content = '<a id="a"><b id="b">hey!</b></a>'; // the body of the new file...
var blob = new Blob([content], { type: "text/xml"});

formData.append("webmasterfile", blob);

var request = new XMLHttpRequest();
request.open("POST", "http://foo.com/submitform.php");
request.send(formData);

详见: Creating a FormData object from scratch

可以用FormData循环append file, 但是不能一下append整个file array.

<el-upload
  class="upload-demo"
  ref="upload"
  :limit="2"
  :action="uploadUrl"
  :auto-upload="false"
  :on-change="onChange"
  :on-remove="onRemove"
  :on-progress="onLicenseProgress"
  :on-success="onLicenseUploaded"
  :on-error="onLicenseError">
  <el-button slot="trigger" size="small" type="success">Select files</el-button>
  <div class="el-upload__tip" slot="tip">Please .../div>
</el-upload>
onChange(file, fileList) {
  this.fileList = fileList;
},
onRemove(file, fileList) {
  this.fileList = fileList;
},
upload() {
  let formData = new FormData();

  let fileExts = [];

  this.fileList.forEach(file => {
    formData.append('files', file.raw);
    fileExts.push(file.name.slice(-3));
  });

  if (fileExts.includes("lic") && fileExts.includes('dat')) {
    uploadFile(this.uploadUrl, formData)
      .then(res => {
        this.onLicenseUploaded(res);
      })
      .catch(err => {
        this.onLicenseError(err);
      });
  } else {
    console.log(fileExts);
    this.$message({type: 'error', message: 'You must ...'});
  }

},
uniquejava commented 6 years ago

Vue

File Upload Progress Indicator with Axios and VueJS

ElementUI

element-ui upload组件可否使用 axios通信

可以通过 el-upload 的 beforeUpload方法中通过aixos post。方法return false,这样el-upload就不会再 post了。

      let param = new FormData()  // 创建form对象
      param.append('file', file, file.name)  // file对象是 beforeUpload参数
      let config = {
        headers: {'Content-Type': 'multipart/form-data'}
      }
     // 添加请求头
    axios.post('http://172.19.26.60:8081/rest/user/headurl', param, config)
        .then(response => {
          if (response.data.code === 0) {
            self.ImgUrl = response.data.data
          }
          console.log(response.data)
        })
    }

    return false