cordova+jquery form上传里面的一些诡异坑
在浏览器里面执行很正常的代码,打包到手机上测试就出问题了,浏览器中的执行版本如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>up test</title>
</head>
<body>
<h1>上传测试</h1>
<p></p>
<br>
<form enctype="multipart/form-data" id="doUpfile">
<input type="file" name="file">
</form>
<button id="yes">Do it!</button>
<script src="./libs/jquery.js"></script>
<script src="./libs/jquery.form.js"></script> <script>
window.localStorage.removeItem("token");
var userinfo="username=test&password=123";
$.ajax({
"url":"http://192.168.1.1:9090/common/users/logon",
"type":"POST",
"crossDomain":true,
"data":userinfo,
"success":parse1
})
function parse1(data1){
window.localStorage.setItem("token",data1);
alert("新的token:"+window.localStorage.getItem("token"));
}
alert("token值是:"+window.localStorage.getItem("token"));
alert(userinfo);
var options={
"url":"http://192.168.1.1:9090/club_activity/club/image/clubImage?authToken="+window.localStorage.getItem("token"),
"type":"POST",
"success":parse2,
"error":parse3
} $("#yes").on("click",upSubmit);
function upSubmit(){
$(function(){
$("#doUpfile").ajaxSubmit(options);
})
}
function parse2(data2){
console.log(data2);
alert("上传成功,图片返回值为:"+data2);
alert(JSON.stringify(options));
}
function parse3(data3){
alert("上传出错,原因为:"+data3);
alert(JSON.stringify(data3));
alert(JSON.stringify(options));
alert("token值是:"+window.localStorage.getItem("token"));
}
</script>
</body>
</html>
最初的问题是进入app后点击上传选择文件时,如果直接选择文件的话app就崩溃了,但是如果从侧边栏选择进入“图库”,再在图库里面选择相册,进入相册之后再点选图片,就可以正常选择图片了(这是第一个诡异的地方),直到现在都不知道是为什么。
第二个问题是每次进入app之后弹出来的token是Null(这说明第19行的代码此时已经被执行过了),再弹出userinfo的值,过后再弹出“新的token是:xxxxxx”,也就是说第32行的代码先于第21行的ajax请求执行了(这里代码执行顺序为19-32-33-21),当然也可能不是先于ajax执行,而是先于ajax里面的回调函数parse1执行了。
然后针对第二个问题,一开始以为是localStorage的写法问题,因为刚开始我用的是window.localStorage.key=value的方式来对localStorage存取的,但是后来在stackoverflow上查到在手机上据说是要这么写window.localStorage.setItem(key,value),window.localStorage.getItem(key),window.localStorage.removeItem(key),或者window.localStorage.[key]=value的方式,于是乎改成用setItem()来设置值,但是上传还是失败了,还是因为token的问题导致身份验证失败。仔细一看,每次提交请求的时候,带上的token都是上次的token,但是每次进入app的时候都会发一次请求获得新的token,猜想可能是js代码在浏览器上和在手机上的解析方式不太一样(虽然都是webkit内核,但肯定会有所区别)。
为了验证猜想,加了几条打印代码,作为调试用:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>up test</title>
</head>
<body>
<h1>最新上传测试 version 12-11-options单独定义</h1>
<p></p>
<br>
<form enctype="multipart/form-data" id="doUpfile">
<input type="file" name="file">
</form>
<button id="yes">Do it!</button>
<script src="./libs/jquery.js"></script>
<script src="./libs/jquery.form.js"></script> <script>
window.localStorage.removeItem("token");
var userinfo="username=pengli&password=pengli";
$.ajax({
"url":"http://192.168.1.1:9090/common/users/logon",
"type":"POST",
"crossDomain":true,
"data":userinfo,
"success":parse1
})
function parse1(data1){
window.localStorage.setItem("token",data1);
alert("新的token:"+window.localStorage.getItem("token"));
}
alert("第32行,现在的token值是:"+window.localStorage.getItem("token"));
alert(userinfo); var options={
"url":"http://192.168.1.1:9090/club_activity/club/image/clubImage?authToken="+window.localStorage.getItem("token"),
"type":"POST",
"success":parse2,
"error":parse3
}
alert("第41行,options里面的操作:"+options["url"]);
$("#yes").on("click",upSubmit);
function upSubmit(){
$(function(){
$("#doUpfile").ajaxSubmit(options);
})
}
function parse2(data2){
console.log(data2);
alert("上传成功,图片返回值为:"+data2);
alert("最后的token值是:"+window.localStorage.getItem("token"));
alert(JSON.stringify(options));
}
function parse3(data3){
alert("上传出错,原因为:"+data3);
alert(JSON.stringify(data3));
alert(JSON.stringify(options));
alert("最后的token值是:"+window.localStorage.getItem("token"));
}
</script>
</body>
</html>
在手机里面,代码的执行顺序为:先弹出第32行(现在的token值是Null,当然,这说明19行是最先执行的),紧接着弹出第33行的userinfo值,第三次是执行第41行的代码(第41行,options里面的操作:http://192.168.1.1:9090/club_activity/club/image/clubImage?authToken=null),最后弹出第30行的代码(新的token值是xxxxx)。
而在浏览器中,执行的效果为:第32行(现在的token为Null),紧接着是第30行(新的token值是xxxx,说明此时已经取到了token),再然后是执行第33行代码,弹出Userinfo的值,最后是第41行代码,Options操作里面的token已经不是Null,而是获取到的token了。也就是说,Js在浏览器和在手机上的执行确实存在顺序上的不一致,这种解析方式的差异,多半就是webkit内核不同导致的。
解决方式有两种:第一种是单独另写一个登陆页,现在这个页面发起请求获得token,然后再进入文件上传页面上传文件。另一种,如果非得把上传和提交写在一个页面里面,那就不能把$.ajaxSubmit()的操作单独定义出来,而是要直接传进去,即:
function upSubmit(){
$(function(){
$("#doUpfile").ajaxSubmit({
"url":"http://192.168.1.1:9090/club_activity/club/image/clubImage?authToken="+window.localStorage.getItem("token"),
"type":"POST",
"success":parse2,
"error":parse3
});
})
}
还有需要注意的一个地方是,使用cordova打包app时,需要加入whitelist插件,否则上传会一直返回404错误,具体的请参考:http://gxxsite.com/content/view/id/197.html
另外由于在手机上传文件,需要文件访问权限,cordova打包时还需要加入cordova-plugin-file和cordova-plugin-file-transfer两个插件。
有关cordova打包的具体细节,参考这里:http://blog.csdn.net/g252691665/article/details/50259471
cordova+jquery form上传里面的一些诡异坑的更多相关文章
- jquery.form上传文件
建立test文件夹 PHP代码: <?php //var_dump($_FILES['file']);exit; if(isset($_GET['option']) && $_G ...
- jQuery.form 上传文件
今年大部分是都在完善产品,这几天遇到了一个问题,原来的flash组件不支持苹果浏览器,需要改.在网上搜了下,看到一个jQuery.form插件可以上传文件,并且兼容性很好,主要浏览器大部分都兼容,插件 ...
- IE8/9 JQuery.Ajax 上传文件无效
IE8/9 JQuery.Ajax 上传文件有两个限制: 使用 JQuery.Ajax 无法上传文件(因为无法使用 FormData,FormData 是 HTML5 的一个特性,IE8/9 不支持) ...
- 强大的支持多文件上传的jQuery文件上传插件Uploadify
支持多文件上传的jQuery文件上传插件Uploadify,目前此插件有两种版本即Flash版本和HTML5版本,对于HTML5版本会比较好的支持手机浏览器,避免苹果手机Safari浏览器不支持Fla ...
- jQuery文件上传插件Uploadify(转)
一款基于flash的文件上传,有进度条和支持大文件上传,且可以多文件上传队列. 这款在flash的基础上增加了html5的支持,所以在移动端也可以使用. 由于官方提供的版本是flash免费,html5 ...
- jQuery文件上传插件jQuery Upload File 有上传进度条
jQuery文件上传插件jQuery Upload File 有上传进度条 jQuery文件上传插件jQuery Upload File,插件使用简单,支持单文件和多文件上传,支持文件拖拽上传,有进度 ...
- 聊一聊jquery文件上传(支持多文件上传)
谈到文件上传,现在一般都用现成的组件可以使用.PC端的可以使用uploadify.针对微网站H5也有uploadifive.但是这组件并不能满足各种场景的需求,例如:预览 切图 放大缩小,取消之类的. ...
- ASP.NET Jquery+ajax上传文件(带进度条)
效果图 支持ie6+,chrome,ie6中文文件名会显示乱码. 上传时候会显示进度条. 需要jquery.uploadify.js插件,稍后会给出下载 前台代码 <%@ Page Langua ...
- MVC文件上传 - 使用jquery异步上传并客户端验证类型和大小
本篇体验MVC上传文件,从表单上传过渡到jquery异步上传. MVC最基本的上传文件是通过form表单提交方式 □ 前台视图部分 <% using(Html.BeginForm("F ...
随机推荐
- anaconda学习笔记
anaconda介绍 Anaconda指的是一个开源的Python发行版本,其包含了conda.Python等180多个科学包及其依赖项. Conda是一个开源的包.环境管理器,可以用于在同一个机器上 ...
- 黑马eesy_15 Vue:03.生命周期与ajax异步请求
黑马eesy_15 Vue:02.常用语法 黑马eesy_15 Vue:03.生命周期 黑马eesy_15 Vue:04.Vue案例(ssm环境搭建) vue的生命周期与ajax异步请求 1.Vue的 ...
- 用户界面编程模式 MVC MVP MVVM
用户界面编程模式 MVC MVP MVVM 程序 = 数据 + 算法 数据:就是待处理的东西 算法:就是代码 涉及到人机交互的程序,不可避免涉及到界面和界面上显示的数据原始方式是界面代码和逻辑代码糅合 ...
- vs strcore.cpp(156) 内存泄漏
在一个静态函数的线程回调中,一个cstring的对象没释放. 遇到这种问题: 1.查看所有的指针对象,有没有合适的回收 2.查看代码的malloc,看看有没有free 3.一点一点注释代码,定位位置
- Exchang Online 保护策略
一.恶意软件筛选器 1.配置反恶意软件策略 1.1Exchange管理中心->保护->恶意软件筛选器->双击Default->编辑默认的策略 1.2单击“设置”选项,根据需要进 ...
- Cobbler_自动装系统
Cobbler —自动装系统的操作步骤 Cobbler是一款自动化操作系统安装的实现,与PXE安装系统的区别就是可以同时部署多个版本的系统,而PXE只能选择一种系统. Cobbler 的安装 # 在一 ...
- 搭建solr8
这里记录linux上的安装过程 一.下载安装包 https://lucene.apache.org/solr/downloads.html 二.解压安装 这里我放倒了/usr/local/solr目录 ...
- SimpleDateFormat 线程安全的解决方案--DateTimeFormatter
SimpleDateFormat并不是线程安全的,因为在SimpleDateFormat中持有一个Calendar类对象在Parse 和Format方法时会调用calendar.setTime(dat ...
- 如何查看Linux系统下程序运行时使用的库?
Linux系统下程序运行会实时的用到相关动态库,某些场景下,比如需要裁剪不必要的动态库时,就需要查看哪些动态库被用到了. 以运行VLC为例. VLC开始运行后,首先查看vlc的PID,比如这次查到的V ...
- 应用HTML5 标签下载文件
使用HTML5 <a>标签可以直接下载文件而不用通过后台action. <a href="/uploadfolder/xxxx.txt">点击下载</ ...