在浏览器里面执行很正常的代码,打包到手机上测试就出问题了,浏览器中的执行版本如下:

 <!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上传里面的一些诡异坑的更多相关文章

  1. jquery.form上传文件

    建立test文件夹 PHP代码: <?php //var_dump($_FILES['file']);exit; if(isset($_GET['option']) && $_G ...

  2. jQuery.form 上传文件

    今年大部分是都在完善产品,这几天遇到了一个问题,原来的flash组件不支持苹果浏览器,需要改.在网上搜了下,看到一个jQuery.form插件可以上传文件,并且兼容性很好,主要浏览器大部分都兼容,插件 ...

  3. IE8/9 JQuery.Ajax 上传文件无效

    IE8/9 JQuery.Ajax 上传文件有两个限制: 使用 JQuery.Ajax 无法上传文件(因为无法使用 FormData,FormData 是 HTML5 的一个特性,IE8/9 不支持) ...

  4. 强大的支持多文件上传的jQuery文件上传插件Uploadify

    支持多文件上传的jQuery文件上传插件Uploadify,目前此插件有两种版本即Flash版本和HTML5版本,对于HTML5版本会比较好的支持手机浏览器,避免苹果手机Safari浏览器不支持Fla ...

  5. jQuery文件上传插件Uploadify(转)

    一款基于flash的文件上传,有进度条和支持大文件上传,且可以多文件上传队列. 这款在flash的基础上增加了html5的支持,所以在移动端也可以使用. 由于官方提供的版本是flash免费,html5 ...

  6. jQuery文件上传插件jQuery Upload File 有上传进度条

    jQuery文件上传插件jQuery Upload File 有上传进度条 jQuery文件上传插件jQuery Upload File,插件使用简单,支持单文件和多文件上传,支持文件拖拽上传,有进度 ...

  7. 聊一聊jquery文件上传(支持多文件上传)

    谈到文件上传,现在一般都用现成的组件可以使用.PC端的可以使用uploadify.针对微网站H5也有uploadifive.但是这组件并不能满足各种场景的需求,例如:预览 切图 放大缩小,取消之类的. ...

  8. ASP.NET Jquery+ajax上传文件(带进度条)

    效果图 支持ie6+,chrome,ie6中文文件名会显示乱码. 上传时候会显示进度条. 需要jquery.uploadify.js插件,稍后会给出下载 前台代码 <%@ Page Langua ...

  9. MVC文件上传 - 使用jquery异步上传并客户端验证类型和大小

    本篇体验MVC上传文件,从表单上传过渡到jquery异步上传. MVC最基本的上传文件是通过form表单提交方式 □ 前台视图部分 <% using(Html.BeginForm("F ...

随机推荐

  1. Iterator接口(迭代器)的使用

    Iterator接口(迭代器) 前言 在程序开发中,经常需要遍历集合中的所有元素.针对这种需求,JDK专门提供了一个接口java.util.Iterator.Iterator接口也是Java集合中的一 ...

  2. 5G时代将至,哪些改变会随之而来?

    近年来,运营商不断被唱衰.关键原因就在于运营商的各项业务,在互联网的冲击下已经愈发"萎缩".尤其是短信和语音通话,它们的价值在不断被降低.简而言之,运营商似乎成为了纯粹的" ...

  3. sql的书写顺序

    例:select t.* from (select *  from t_user where isDelete = 1 limit 0,10) t order by t.qq select from ...

  4. JAVA并发思维导图

    原博客:https://blog.csdn.net/oqkdws/article/details/82145389

  5. Linux基础篇五:文件操作篇(三剑客)

    cut截取字段: -d  指定分割符 -f   指定第几列 例题1: echo "i am dusonglin ,my qq is  380343680 " >dusongl ...

  6. PAT甲级——1025 PAT Ranking

    1025 PAT Ranking Programming Ability Test (PAT) is organized by the College of Computer Science and ...

  7. 微信中的APP、公众号、小程序的openid及unionid介绍

    微信中的APP.公众号.小程序的openid及unionid介绍 1.unionid 如果开发者拥有多个移动应用.网站应用.和公众帐号(包括小程序),可通过 UnionID 来区分用户的唯一性,因为只 ...

  8. linux通过grep根据关键字查找日志文件上下文

    linux通过grep根据关键字查找日志文件上下文 1.在标准unix/linux下的grep命令中,通过以下参数控制上下文的显示: grep -C 10 keyword catalina.out 显 ...

  9. jsp页面链接文件

    Myeclipse中jsp页面链接css文件不生效问题 jsp页面在外链css文件后,样式表不生效,查了很多方法,都说是路径问题改了很多次也不行. 例如改为: <link rel="s ...

  10. Angular开发者指南(二)概念概述

    template(模板):带有附加标记的模板HTML directives(指令):使用自定义属性和元素扩展HTML model(模型):用户在视图中显示的数据,并与用户进行交互 scope(作用域) ...