上传文件与与上传数据区别

上传数据主要指json等简单字符串,上传文件指的是上传word、excel图片等。在上传数据的时候enctype默认为第一个application/x-www-form-urlencoded,而上传数据包含文件的时候要用第二种multipart/form-data

 

描述
application/x-www-form-urlencoded 在发送前编码所有字符(默认)url编码
multipart/form-data

不对字符编码。

在使用包含文件上传控件的表单时,必须使用该值。

text/plain 空格转换为 "+" 加号,但不对特殊字符编码。

 

 

 

 

文件上传在WEB开发中应用很广泛,我们经常发微博、发微信朋友圈都用到了图片上传功能。

文件上传是指将本地图片、视频、音频等文件上传到服务器上,可以供其他用户浏览或下载的过程。

今天我给大家聊聊常见的文件(图片)上传的方式和要点处理。

表单上传

这是传统的form表单上传,使用form表单的input[type=”file”]控件,可以打开系统的文件选择对话框,从而达到选择文件并上传的目的,它的好处是多浏览器兼容,它是web开发者最常用的一种文件上传方式。

表单的代码如下:

<formmethod="post"action="http://uploadUrl"enctype="multipart/form-data">

   <inputname="file"type="file"accept="image/gif,image.jpg"/>

   <inputname="token"type="hidden"/>

   <inputtype="submit"value="提交"/>

</form>

以下是表单上传几个关键点:

  • method=”post”: 采用post方式提交数据
  • enctype=”multipart/form- data”:采用multipart格式上传文件,此时request头会显示 Content-Type:multipart/form-data; boundary=—-WebKitFormBoundaryzr34cwJ67R95KQC9
  • action:标明上传的服务端处理地址
  • type=”file”:使用input的file控件上传
  • 如果是多文件批量上传,可以将input[type=”file”]的name属性设置为如:name=”file[]”
  • accept属性是HTML5的新属性,它规定了可通过文件上传提交的文件类型
  • 上传的触发事件可以是:input[type=”file”]的onChange触发,也可以由一个独立的按钮的onClick使整个表单提交,此时还可以用input[type=”hidden”]带一些其它的参数,比如Token来源验证等等。

Ajax无刷新上传

Ajax无刷新上传的方式,本质上与表单上传无异,只是把表单里的内容提出来采用ajax提交,并且由前端决定请求结果回传后的展示结果,不用像直接表单上传那样刷新和跳转页面。在这里,我们采用jQuery来作为操作DOM和创建ajax提交的js基础库。

html代码片段如下:

<form>

   <input/>

   <input/>

</form>

JavaScript代码片段如下:

$("#file").on("change",function(){

 var formData =newFormData();

  formData.append("file", $("#file")[0].files);

  formData.append("token", $("#token").val());

  $.ajax({

      url:"http://uploadUrl",

      type:"POST",

      data: formData,

      processData:false,

      contentType:false,

      success:function(response){

             //根据返回结果指定界面操作

      }

  });

});

我们使用了file控件的change来触发上传事件,当然你也可以使用某个按钮来触发表单提交。提交数据时,我 用到了FormData对象来发送二进制文件,FormData构造函数提供的append()方法,除了直接添加二进制文件还可以附带一些其它的参数, 作为XMLHttpRequest实例的参数提交给服务端。

使用jquery提供的ajax方法来发送二进制文件,还需要附加两个参数:

  • processData: false // 不要对data参数进行序列化处理,默认为true
  • contentType: false // 不要设置Content-Type请求头,因为文件数据是以 multipart/form-data 来编码

表单上传和ajax上传实质是一样的,只不过表单上传已经封装好了,比较浅显,ajax比较容易控制

 

上传与安全

上传文件时必须做好文件的安全性,除了前端必要的验证,如文件类型、后缀、大小等验证,重要的还是要在后台做安全策略。

这里我列举几个注意点:

    • 后台需要进行文件类型、大小、来源等验证
    • 定义一个.htaccess文件,只允许访问指定扩展名的文件。
    • 将上传后的文件生成一个随机的文件名,并且加上此前生成的文件扩展名。
    • 设置上传目录执行权限,避免不怀好意的人绕过如图片扩展名进行恶意攻击,拒绝脚本执行的可能性。

 

转:http://blog.csdn.net/xcymorningsun/article/details/52949848

 

http://blog.sina.com.cn/s/blog_75a555e40101q8i7.html

 

https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/sending-html-form-data-part-2

WEBAPI获取数据文件等

/// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<HttpResponseMessage> PostFormData()
        {
            // 检查该请求是否含有multipart/form-data 
            if (!Request.Content.IsMimeMultipartContent("form-data"))
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }
            // 文件保存目录路径
            const string saveTempPath = "~/UploadFiles/";
            var dirTempPath = HttpContext.Current.Server.MapPath(saveTempPath);
            // 设置上传目录 
            var provider = new MultipartFormDataStreamProvider(dirTempPath);

            try
            {
                // 读取表单数据 
                await Request.Content.ReadAsMultipartAsync(provider);
                // 显示所有“键-值”对  
                foreach (var key in provider.FormData.AllKeys)
                {
                    foreach (var val in provider.FormData.GetValues(key))
                    {
                        System.Diagnostics.Trace.WriteLine(string.Format("{0}: {1}", key, val));
                    }
                }

                // 以下描述如何获取文件名    
                //TODO:这样做直接就将文件存到了指定目录下,暂时不知道如何实现只接收文件数据流但并不保存至服务器的目录下,由开发自行指定如何存储,比如通过服务存到图片服务器 
                foreach (MultipartFileData file in provider.FileData)
                {
                    System.Diagnostics.Trace.WriteLine(file.Headers.ContentDisposition.FileName);//获取上传文件实际的文件名
                    System.Diagnostics.Trace.WriteLine("Server file path: " + file.LocalFileName);//获取上传文件在服务上默认的文件名
                }
                return Request.CreateResponse(HttpStatusCode.OK);
            }
            catch (Exception ex)
            {
                return Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex);
            }
        }
WEBAPI

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-01-13
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
猜你喜欢
  • 2022-03-10
  • 2021-09-09
  • 2021-09-16
  • 2022-12-23
  • 2022-12-23
  • 2021-07-19
  • 2022-12-23
相关资源
相似解决方案