Angular2使用ng2-file-upload上传文件

作者: Shmily落墨 | 来源:发表于2016-12-20 13:02 被阅读22606次

    Angular2中有两个比较好用的上传文件的第三方库,一个是ng2-file-upload,一个是ng2-uploaderng2-uploader是一个轻便的上传文件的支持库,功能较弱,而ng2-file-upload是一个功能比较全面的上传文件的支持库。这里主要介绍一下ng2-file-upload的使用。

    以下以Mac OS操作系统介绍。


    1. 安装

    使用npm安装即可。在项目中打开“终端”,运行命令:

    sudo npm install ng2-file-upload --save
    

    如果是以systemjs的方式打包,安装完成后需要打开systemjs.config.js文件,在System.configmap字段中的最后一行输入以下字段:

    'ng2-file-upload':            'npm:ng2-file-upload'
    

    System.configpackages字段中的最后一行输入:

    'ng2-file-upload': {    
        main: 'index.js',    
        defaultExtension: 'js'
    }
    

    之后便可以在项目中使用了。


    2. 使用

    在需要用到的模块中引用模块:

    import { CommonModule }     from '@angular/common';
    import { FileUploadModule } from 'ng2-file-upload';
    

    然后在@NgModuleimports字段中引用CommonModuleFileUploadModule

    在对应需要使用的组件内引用:

    import { FileUploader } from 'ng2-file-upload';
    

    初始化FileUploader

    uploader:FileUploader = new FileUploader({    
        url: "http://www.download.com:80/uploadFile",   
        method: "POST",    
        itemAlias: "uploadedfile"
    });
    

    初始化FileUploader需要传入FileUploaderOptions类型的参数:

    | 参数名 | 参数类型 | 是否是可选值 | 参数说明 |
    |:---- --:|:--------:|:-------------:|:--------:|
    | allowedMimeType | Array<string> | 可选值 | |
    | allowedFileType | Array<string> | 可选值 | 允许上传的文件类型 |
    | autoUpload | boolean | 可选值 | 是否自动上传 |
    | isHTML5 | boolean | 可选值 | 是否是HTML5 |
    | filters | Array<FilterFunction> | 可选值 | |
    | headers | Array<Headers> | 可选值 | 上传文件的请求头参数 |
    | method | string | 可选值 | 上传文件的方式 |
    | authToken | string | 可选值 | auth验证的token |
    | maxFileSize | number | 可选值 | 最大可上传文件的大小 |
    | queueLimit | number | 可选值 | |
    | removeAfterUpload | boolean | 可选值 | 是否在上传完成后从队列中移除 |
    | url | string | 可选值 | 上传地址 |
    | disableMultipart | boolean | 可选值 | |
    | itemAlias | string | 可选值 | 文件标记/别名 |
    | authTokenHeader | string | 可选值 | auth验证token的请求头 |

    2.1 选择文件

    在组件对应的HTML模版中设置input标签:

    <input type="file" ng2FileSelect [uploader]="uploader" (change)="selectedFileOnChanged($event)" />
    

    在组件.ts文件中设置声明函数:

    selectedFileOnChanged() {
        // 这里是文件选择完成后的操作处理
    }
    

    选择文件默认支持选择单个文件,如需支持文件多选,请在标签中添加multiple属性,即:

    <input type="file" ng2FileSelect [uploader]="uploader" (change)="selectedFileOnChanged($event)" multiple />
    
    2.2 拖拽文件

    拖拽文件默认支持多文件拖拽。
    对块级元素进行设置(这里以div标签为例):

    <div class="beforeDrop" ng2FileDrop [ngClass]="{dropping: isDropZoneOver}" (fileOver)="fileOverBase($event)" (onFileDrop)="fileDropOver($event)" [uploader]="uploader"><div>
    

    在组件.ts文件中设置声明函数:

    fileOverBase(event) {
        // 拖拽状态改变的回调函数
    }
    fileDropOver(event) {
        // 文件拖拽完成的回调函数
    }
    
    2.3 文件上传

    FileUploader有个数组类型的属性queue,里面是所有拖拽的和选择的文件,只要操作这个属性便可以进行文件上传。

    this.uploader.queue[0].onSuccess = (response, status, headers) => {    
        // 上传文件成功   
        if (status == 200) {
            // 上传文件后获取服务器返回的数据
            let tempRes = JSON.parse(response);        
        }else {            
            // 上传文件后获取服务器返回的数据错误        
        }
    };
    this.uploader.queue[0].upload(); // 开始上传
    

    3. FileUploader详解

    FileUploader是ng2-file-upload最主要的部件,里面包含了所有对文件的处理。

    3.1 属性详解
    • isUploading:[boolean] 是否正在上传文件中。
    • queue:[array<FileItem>] 已经拖拽或选择的所有文件。
    • progress:[number] 所有的上传文件的整体进度。
    • options:[FileUploaderOptions] 上传文件的配置信息,前面已经介绍过。
    3.2 方法详解
    • setOptions(options: FileUploaderOptions): void;
      设置上传文件的配置信息。
    • addToQueue(files: File[], options?: FileUploaderOptions, filters?: FilterFunction[] | string): void;
      手动添加文件到FileUploader的上传队列中。
    • removeFromQueue(value: FileItem): void;
      FileUploader的上传队列中移除指定文件。
    • clearQueue(): void;
      清除FileUploader上传队列中的所有文件。
    • uploadItem(value: FileItem): void;
      上传指定文件。
    • cancelItem(value: FileItem): void;
      取消指定文件的上传。
    • uploadAll(): void;
      上传FileUploader的上传队列中的所有文件。
    • cancelAll(): void;
      取消FileUploader的上传队列中的所有文件的上传。
    • isFile(value: any): boolean;
      判断是否是文件。
    • getIndexOfItem(value: any): number;
      获取文件在FileUploader上传队列中的位置。
    • getNotUploadedItems(): Array<any>;
      获取FileUploader上传队列中的所有未上传的文件。
    • getReadyItems(): Array<any>;
      获取FileUploader上传队列中的所有准备上传的文件。
    • destroy(): void;
      销毁FileUploader实例。
    3.3 监听详解
    • onAfterAddingAll(fileItems: any): any;
      添加完所有文件之后的回调
      返回:
    • fileItems - 添加的文件的数组
    • onBuildItemForm(fileItem: FileItem, form: any): any;
      创建文件之后的回调
      返回:
    • fileItem - 创建的文件
    • form - 添加的方式
    • onAfterAddingFile(fileItem: FileItem): any;
      添加一个文件之后的回调
      返回:
    • fileItem - 添加的文件
    • onWhenAddingFileFailed(item: FileLikeObject, filter: any, options: any): any;
      添加文件失败的回调
      返回:
    • item -
    • filter -
    • options -
    • onBeforeUploadItem(fileItem: FileItem): any;
      要上传文件之前的回调
      返回:
    • fileItem - 将要上传的文件
    • onProgressItem(fileItem: FileItem, progress: any): any;
      上传文件的进度(开始上传后调用非常频繁)
      返回:
    • fileItem - 正在上传的文件
    • progress - 该文件的上传进度
    • onProgressAll(progress: any): any;
      整体的上传进度的回调(开始上传后调用非常频繁)
      返回:
    • progress - 整体的上传文件的进度
    • onSuccessItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any;
      上传一个文件成功的回调
      返回:
    • item - 上传成功的文件
    • response - 上传成功后服务器的返回
    • status - 状态码
    • headers - 上传成功后服务器的返回的返回头
    • onErrorItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any;
      上传一个文件错误的回调
      返回:
    • item - 上传错误的文件
    • response - 返回的错误
    • status - 状态码
    • headers - 返回的错误返回头
    • onCancelItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any;
      取消上传一个文件的回调
      返回:
    • item - 取消上传的文件
    • response - 取消的返回信息
    • status - 状态码
    • headers - 取消的返回信息的返回头
    • onCompleteItem(item: FileItem, response: string, status: number, headers: ParsedResponseHeaders): any;
      完成上传一个文件的回调
      返回:
    • item - 上传成功的文件
    • response - 上传成功后服务器的返回
    • status - 状态码
    • headers - 上传成功后服务器的返回的返回头
    • onCompleteAll(): any;
      完成上传所有文件的回调

    4. FileItem详解

    FileItemFileUploaderqueue属性的元素类型,在FileUploader中存储的文件的基本类型。

    4.1 属性详解
    • alias [string] : 上传的标志/别名。
    • url [string] : 地址。
    • method [string] : 上传的方法。
    • headers [any] : 上传的头部参数。
    • withCredentials: [boolean] : 是否使用证书。
    • formData [any] : 格式化数据?
    • isReady [boolean] : 是否准备上传(是否可以上传)。
    • isUploading [boolean] : 是否正在上传。
    • isUploaded [boolean] : 是否已经上传过。
    • isSuccess [boolean] : 是否上传成功。
    • isCancel [boolean] : 是否取消上传。
    • isError [boolean] : 是否上传错误。
    • progress [number] : 上传进度。
    • index [number] : 在队列中的位置。
    4.2 方法详解
    • upload(): void;
      开始上传这个文件。
    • cancel(): void;
      取消上传这个文件。
    • remove(): void;
      将这个文件从上传队列中移除。
    4.3 监听详解
    • onBeforeUpload(): void;
      开始上传之前的回调函数。
    • onBuildForm(form: any): any;
      创建文件的回调函数。
      返回:
    • form - 文件来源。
    • onProgress(progress: number): any;
      上传文件的进度回调函数。
      返回:
    • progress - 上传文件的进度。
    • onSuccess(response: string, status: number, headers: ParsedResponseHeaders): any;
      上传文件成功的回调函数。
      返回:
    • response - 成功后的回调数据
    • status - 状态码
    • headers - 回调数据的返回头
    • onError(response: string, status: number, headers: ParsedResponseHeaders): any;
      上传文件错误的回调函数。
    • onCancel(response: string, status: number, headers: ParsedResponseHeaders): any;
      取消上传的回调函数。
    • onComplete(response: string, status: number, headers: ParsedResponseHeaders): any;
      上传文件完成的回调函数。

    相关文章

      网友评论

      • ecc18e84d9b0:写的真赞哦
      • clp简:用ajax和postman都可以上传文件。按照以上步骤用ng2-file-upload插件,就一直提示跨域的问题。应该不是跨域的问题,请问该如何解决。
        clp简:@YasuoYuHao 谢谢大神
        YasuoYuHao:自定義 onAfterAddingFile
        增加
        fileItem.withCredentials = false;
      • 尚雪36号:上传文件在angular4项目里用没问题,现在用ng build --prod --aot
        命令压缩项目部署到服务器上打开报错TypeError: Cannot read property 'create' of undefined
        不知道博主有什么解决的办法或想法?
      • 大胖圆儿小姐:需要在上传文件的时候传一些参数,需要怎么添加啊,添加在option里面无法传到后台,参数中只有excel文件
        YasuoYuHao:首先先在你的component.ts中,建構器中設定自定義onBuildItemForm,範例如下:
        constructor() {
        this.uploader.onBuildItemForm = this.onBuildItemForm.bind(this);
        }

        然後在同一個 component 中,建立自定義的 onBuildItemForm ,範例如下:

        onBuildItemForm(fileItem: FileItem, form: any): any {
        if (isDevMode()) {
        console.log('onBuildItemForm');
        }
        form.append('key', value);
        return { fileItem, form };
        }

        如此一來就能自定義參數到 form data 裡面
      • zcxzcxczcx:我上传的地址写的是http://localhost:4200,然后一直报404,找不到该路径的错,是为什么呢
      • 38bc1e8d0a69:你好,请问我批量上传,目前有没有什么好办法去监听返回值呢,目前使用了uploadAll(),虽然它是逐条上传,但是我搜索了一下,还没有好的办法可以监听到每条请求的返回
      • 31b1810e1581:有遇到过上传视频限制视频格式的吗,比如只让上传MP4的格式的视频,求解
      • 梦_f66d:文件比较大http出现504超时的时候应该调用那个方法比较合适,还有进度条问什么一直为0
      • 小夫特:你好,我问一下,这边传给后台的文件流是直接传过去,后台解析的么,不需要前台以json的形式传过去么。
      • 7cadc87cf420:有两个问题,设置allowedFileType(允许上传类型)报错,我是这样写的allowedFileType: ["jpg", "png"],不知打为什么,还有就是上传文件成功后使用onSuccessItem方法,在该方法内使用ElementRef来操作DOM报错:Cannot read property 'nativeElement' of undefined
        YasuoYuHao:1. type 應該要符合MIME types的格式,比如["image/jpeg", "image/png"]
        2. 操作DOM層 是使用 @viewchild 嗎,如果是檢查一下ngif或是disable,這會影響操作DOM
      • 木辛_848f:为什么头部headers: {'Authorization': 'Bearer ' + this.ls.getObject('token')},会一直报错的?
        YasuoYuHao:public uploader: FileUploader = new FileUploader({
        method: 'POST',
        allowedMimeType: ['application/zip', 'application/octet-stream', 'application/x-zip-compressed', 'multipart/x-zip'],
        url: environment.BaseApiUrl + 'upload/products',
        isHTML5: true,
        authToken: localStorage.getItem('token'),
        authTokenHeader: 'authorization'
        });
        木辛_848f:headers: [{'Authorization': 'Bearer ' + this.ls.getObject('token')}]也不行的,求答
      • LiUhoNg_Dan:那个url地址那个是直接写服务器的地址吗?
        YasuoYuHao:restful api url
      • zenglaoda:您好,请问如何在上传图片的时候带点数据上去,
        YasuoYuHao:onBuildItemForm 時
        form.append
      • 838e0364912b:你好,上传一次之后不能再上传,要刷新一次页面才能再上传,和onSuccessItem这个回调方法里面调用不了类里面的其他方法,希望题主能指导一下:blush:
        YasuoYuHao:this.uploader.onSuccessItem = this.onSuccessItem.bind(this);
        87a069e72c6d:我也遇到这个问题。你们有人解决吗?
        31b1810e1581:请问这个问题你解决了吗
      • 6b0ebed32ecb:请问,我上传的文件fileName是中文的,但是java后台得到的却是一个??.txt 这样的文件,后台做了转码还是不行。我页面上meta写的也是charset=‘utf-8’,这种情况应该怎么解决?
        YasuoYuHao:我的建議是,上傳時先用別名,把檔名記錄到資料庫,下載的時候再帶進來
        Haozj:你好,同样遇到中文名问题,请问您是怎么解决的?上传成功了,但是在下载的时候就会报错。
      • 萌小希_e9d8:请问一下如何获取已经选择的文件的本地路径?就是在未上传之前获取到该文件的本地路径~请问ng-file-uploader可以做到吗?
        YasuoYuHao:自定義 input, 取得你要的資訊之後, 再用程式去加入
      • 31e23d0a0c85:ng4能用吗?
      • 维所欲維:楼主有源码吗??嘻嘻
      • 萌小希_e9d8:请问一下作者大大,怎么获取上传文件的本地路径呢? 不清楚ts里面有关路径的用法
        YasuoYuHao:跟js一樣,會fileitem裡面應該也有
      • Keriy:请教一下,进度条的参数不变都有哪些可能,找不到问题。
        Shmily落墨:@Keriy 你是如何写的回掉?
        Keriy: @Shmily落墨 上传成功了,我也拿到返回数据了,但是整个过程中uploader.progress一直为0
        Shmily落墨:@Keriy 没上传上去吧?
      • Keriy:什么时候写一个详细的呀,这个没用到什么呀。
        Keriy: @Shmily落墨 不用不用…😬
        Shmily落墨:@Keriy 还想要怎么详细?翻译源码吗?
      • 野火冉冉:你好,问一下,这段时间使用发现,这个组件发送文件时,是按照单文件发送,就算队列里面有多个文件也是分开发送,好像没有可以配置的地方
        Shmily落墨:@野火冉冉 应该是,等我过两天看看源码能不能解决这个问题,或者你可以去这个项目的GitHub上提问看看
      • 用户体验:你好,如何限制文件类型?allowedFileType 如何使用,比如我只能选择pdf文件。
        用户体验:@Shmily落墨 好滴,谢谢啦。。。
        Shmily落墨:@用户体验 在input标签中设置,这个属于HTML的内容,这里不再介绍
      • 老K_25a4: public uploader:FileUploader = new FileUploader({
        url: "/ng2/uploadFile" ,
        method: "POST",
        itemAlias: "uploadedfile"
        });


        我在用这个URL 上传的时候一直报 POST 404 错,URL Not Found ,请问 需要特殊设置吗
        枫影丨林夕:@Shmily落墨 这个上传需要后台吗?直接angular2是不是会报路径找不到?上传到本地报了路径Not Found。
        Shmily落墨:@老K_25a4 url写你要上传的地址,itemAlias一般不用填写
      • 野火冉冉:rollup 打包时,'FileUploadModule' is not exported by node_modules/ng2-file-upload/index.js
        版本是"version": "1.2.1",
        Shmily落墨:@野火冉冉 没有所谓的达到达不到发布要求,有bug可以直接改库的源码
        野火冉冉:@Shmily落墨 这样的话,岂不是angular2 的组件稳定性和兼容性,达不到发布需求。
        Shmily落墨:@野火冉冉 抱歉,没用过rollup,不太清楚它的打包过程,目测你应该是在rollup打包配置中少了对这个库的配置
      • Mezereon:请问一下,如果我在上传之前设置队列中的formdata,比如
        this.formdata.append('introduction', this.content);
        this.uploader.queue[0].formData = this.formdata;
        这样是否就可以设置post的额外参数了?
        nginx_9c96:请问你上传参数成功了吗?
        6f5892321a2e:this.uploader.onBuildItemForm = function(fileItem, form){
        form.append('pubImgRandNum', '1');
        };添加自定义参数
        Shmily落墨:@Mezereon 你可以尝试一下,之前我们的项目并没有用到上传时附带参数,我们文件以及上传对文件的参数是分两个接口传输的。
      • Exception_22bf:你好,请问我上传文件比较大时 请求头出现Provisional headers are shown是怎么回事啊?
        Shmily落墨:@Exception_22bf 不清楚你的具体代码,无法做出判断,我之前上传几百兆的也没有出现过这种状况
      • cd442e32055a:如果想上传图片的同时带两个参数应该怎么写?
        Shmily落墨:@Crystal大露子 见11楼回复
        cd442e32055a:additionalParameter是传附加参数的吗??
      • 6fb94dc126c5:像onCompleteItem这种回调怎么使用呢??
      • 叶长风:博主,我后台是koa2,我解决了cors,但是一点击上传就报XMLHttpRequest cannot load http://localhost:3005/api/uploadImage. Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. Origin 'http://localhost:4200' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute. 是需要在angular代码中解决什么吗?
        clp简:您好,我也是就报这个跨域的问题。但是用ajax可以上传文件,应该不是跨域的问题才对,亲我跟我现在该如何解决。
        Shmily落墨:你这个是跨域问题,可以使用nginx代理一下
      • 72a0358c608a:为什么会遇到跨域问题
        nginx_9c96:请问你解决了吗我也遇到跨域了
        Shmily落墨:我本来都不想回答这个问题。我想反问一下为什么不存在跨域问题?
      • 再无风雨也无情:您好,看了您的文章我前端已经没有问题了,但服务端只能收到
        ------WebKitFormBoundaryfcuQGXaLgGvh8zAZ
        Content-Disposition: form-data; name="uploadedfile"; filename="新建文本文档.txt"
        Content-Type: text/plain


        ------WebKitFormBoundaryfcuQGXaLgGvh8zAZ--,没有看见文件流,
        请问文件内容在什么地方读取呢?方便给一个服务端的demo吗?谢谢
        Shmily落墨:@再无风雨也无情 java我没用过,不过应该会有通用库来解决文件接受的问题的
        再无风雨也无情:@Shmily落墨 谢谢回答,那请问这个文件流怎么转成文件呢?这是什么编码的?我服务器是用java写的。
        Shmily落墨:你看到的这个就是文件流,name="uploadedfile";这个东西如果没有必要不用设置,我设置是因为我这边的服务器有作文件类别处理。我不清楚你的服务器是什么语言写的,所以服务端的demo爱莫能助。
      • 勤快懒人:你好,我在使用这个组件的时候,发送到服务端的数据不能正常获取,你方便放出服务端的样例代码吗? 或者告知一下往服务端传送文件的时候有什么注意事项呢? 谢谢
        Shmily落墨:@勤快懒人 我这边没有这样做,input是单独放置的,因为我这边是需要先请求一个接口后再调用,所以我只是借用input的文件选择click事件,并没有将input展示出来
        勤快懒人:@Shmily落墨 嗯 我刚刚试了一下似乎也不行 我还想问一下,前端在写的时候,是不是必须把这个放在 form标签里面?
        Shmily落墨:我当时也遇到过这种问题,我这边的情况是因为服务端作了fileName的限制,只有fileName为`uploadedfile`时才接收文件,我在初始化FileUploader的时候做了设置,设置itemAlias为uploadedfile就可以了
      • c5bc23873748:谢谢 找到问题所在了 谢谢
        46dd4733156a:他这应该是 uploader: FileUploader = new FileUploader({
        url: "http://www.download.com:80/uploadFile";,
        method: "POST",
        itemAlias: "uploadedfile"
        });没有写而引发的,因为我也是这样的
        14a732d26bd7:您好,能分享一下是怎么解决的嘛?
      • c5bc23873748:您好 按照您的步骤操作了 chang事件选择文件提示这个错误是怎么回事啊?

        EXCEPTION: Error in app/file.html:1:4 caused by: Cannot read property 'options' of undefined

        没有options属性?

      本文标题:Angular2使用ng2-file-upload上传文件

      本文链接:https://www.haomeiwen.com/subject/yzaxmttx.html