最近在做一个图片上传到服务器的功能,之前基本没有什么JS的经验,用的也是网上的插件。做了一个星期才把他弄好,现在做一下总结,方便以后查看。
用的插件是WebUploader,上面有很多例子,我找的例子如下图:
在实例化WebUploader的时候需要修改upload.js文件中的server的地址,这样才能将指定的图片上传到服务器代码如下:
// 实例化 uploader = WebUploader.create({ pick: { id: ‘#filePicker‘, label: ‘点击选择图片‘ }, formData: { uid: 123 }, dnd: ‘#dndArea‘, paste: ‘#uploader‘, swf: ‘Uploader.swf‘, chunked: false, chunkSize: 512 * 1024, server:‘Handler1.ashx‘,//用来处理上传图片的服务 // runtimeOrder: ‘flash‘, //文件过滤 accept: { title: ‘Images‘, extensions: ‘gif,jpg,jpeg,bmp,png‘, mimeTypes: ‘image/*‘ }, });
需要注意的是,Handler1.ashx是一个处理上传图片的服务,用于将上传的图片保存到服务器上,文件代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.IO; using System.Net; using System.Web; using System.Web.Services; namespace JQueryUploadDemo { /// <summary> /// $codebehindclassname$ 的摘要说明 /// </summary> [WebService(Namespace = "http://tempuri.org/")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class UploadHandler : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; context.Response.Charset = "utf-8"; HttpPostedFile file = context.Request.Files["Filedata"]; string uploadPath = HttpContext.Current.Server.MapPath(@context.Request["folder"])+"\\"; if (file != null) { if (!Directory.Exists(uploadPath)) { Directory.CreateDirectory(uploadPath); } file.SaveAs(uploadPath + file.FileName); //下面这句代码缺少的话,上传成功后上传队列的显示不会自动消失 context.Response.Write("1"); } else { context.Response.Write("0"); } } public bool IsReusable { get { return false; } } } }
完成上传时候,前端需要获取服务器返回的数据,用于保存在数据库,找了半天,最后在webuploader.js的_finishFile函数中找到了,这里只显示部分代码:
// 完成上传。 _finishFile: function( file, ret, hds ) { var owner = this.owner; postfilename=ret._raw;//获取服务器返回的参数 return owner .request( ‘after-send-file‘, arguments, function() { file.setStatus( Status.COMPLETE ); owner.trigger( ‘uploadSuccess‘, file, ret, hds ); }) .fail(function( reason ) { // 如果外部已经标记为invalid什么的,不再改状态。 if ( file.getStatus() === Status.PROGRESS ) { file.setStatus( Status.ERROR, reason ); } owner.trigger( ‘uploadError‘, file, reason ); }) .always(function() { owner.trigger( ‘uploadComplete‘, file ); }); },
获取返回的数据之后需要将数据传递到upload.js里面,用于保存到数据库中,upload.js中有stats = uploader.getStats(),是获取返回的一些信息的,在updateStatus函数
下面会贴出代码。但是stats对象中没有获取服务器返回的参数,只返回了上传的基本信息,这时候就需要在webuploader.js中的Queue函数中添加postfilenames属性,方法部分代码如下:
function Queue() { /** * 统计文件数。 * * `numOfQueue` 队列中的文件数。 * * `numOfSuccess` 上传成功的文件数 * * `numOfCancel` 被取消的文件数 * * `numOfProgress` 正在上传中的文件数 * * `numOfUploadFailed` 上传错误的文件数。 * * `numOfInvalid` 无效的文件数。 * * `numofDeleted` 被移除的文件数。 * * `postfilenames` 用来保存返回的文件名 * @property {Object} stats */ this.stats = { numOfQueue: 0, numOfSuccess: 0, numOfCancel: 0, numOfProgress: 0, numOfUploadFailed: 0, numOfInvalid: 0, numofDeleted: 0, numofInterrupt: 0, postfilenames:new Array() };
这个时候就可以在upload.js中的updateStatu方法中将返回的数据写入到数据库中,函数代码如下:
function updateStatus() { var text = ‘‘, stats; if ( state === ‘ready‘ ) { text = ‘选中‘ + fileCount + ‘张图片,共‘ + WebUploader.formatSize( fileSize ) + ‘。‘; } else if ( state === ‘confirm‘ ) { stats = uploader.getStats(); if (stats.uploadFailNum) { text = ‘已成功上传‘ + stats.successNum+ ‘张照片,‘+ stats.uploadFailNum + ‘张照片上传失败,<a class="retry" href="#">重新上传</a>失败图片或<a class="ignore" href="#">忽略</a>‘ } } else { stats = uploader.getStats(); AddImageInfo(stats);//自己添加的函数,将图片信息写入到数据库 text = ‘共‘ + fileCount + ‘张(‘ + WebUploader.formatSize( fileSize ) + ‘),已上传‘ + stats.successNum + ‘张‘; if ( stats.uploadFailNum ) { text += ‘,失败‘ + stats.uploadFailNum + ‘张‘; } } $info.html( text ); }
自己定义了一个函数用于将数据保存在在数据库中,这里用的是ajax和webservice写入到数据库中的,函数代码如下:
//将图片信息写入到数据库 function AddImageInfo(stats) { for (var i = 0;i<stats.postfilenames.length;i++){ var serverUrl = "http://localhost:8888/XXXXX.asmx"; $.ajax({ type: ‘POST‘, url: serverUrl + ‘/XXXXXX‘, data: ‘{ stationAttas:‘ + stats[i].postfilenames[i] + ‘}‘, datatype: "json", headers: { "Content-Type": "application/json" }, success: function (data) {//调用服务成功后返回的数据 alert(data); }, error: function (XMLHttpRequest, textStatus) { alert("XMLHttpRequest.state:" + XMLHttpRequest.state + "-XMLHttpRequest.readyState:" + XMLHttpRequest.readyState + "-textStatus:" + textStatus + "-XMLHttpRequest.responseText:" + XMLHttpRequest.responseText); } }) } }
这样就把一个图片上传的功能实现了。另外一个随笔会介绍如何管理上传的图片。
最近在也在做ArcGIS For Js 的缓冲区查询功能功能,里面也有和一样的功能,顺便记录一下。
在使用缓冲区查询的时候,执行execute函数是,错误函数会弹出如下图所示的提示:
这个是因为:query.geometry是个多边形(含有的point多)导致的web service的url的参数个数大于2048个,而我们这里采用的是get方式(最大的字符数为2048)不是post方式,需要proxy.ashx做处理,需要两个文件proxy.ashx和proxy.config,两个文件需要放在IIS中。在调用查询函数前加入下面两句代码即可。
esriConfig.defaults.io.proxyUrl = "http://localhost/proxy.ashx"; esriConfig.defaults.io.alwaysUseProxy = false;
proxy.config代码如下:
<ProxyConfig mustMatch="true"> <serverUrls> <!-- serverUrl options: url = location of the ArcGIS Server, either specific URL or stem matchAll = true to forward any request beginning with the url token = (optional) token to include for secured service --> <serverUrl url="http://localhost:6080/arcgis/rest/services/Findtask/MapServer/0" matchAll="true" token=""></serverUrl> <serverUrl url="http://localhost:6080/arcgis/rest/services/Findtask/MapServer/0" matchAll="true" token=""></serverUrl> <serverUrl url="http://localhost:6080/arcgis/rest/services/Findtask/MapServer/0" matchAll="true"></serverUrl> <serverUrl url="http://localhost:6080/arcgis/rest/services/Findtask/MapServer/0" matchAll="true"></serverUrl> </serverUrls> </ProxyConfig>