├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── wifi │ │ ├── css │ │ └── style.css │ │ ├── images │ │ ├── bg1_01.jpg │ │ ├── bg1_02.jpg │ │ ├── bg_drag.png │ │ ├── bg_file_list.jpg │ │ ├── bg_files.jpg │ │ ├── bg_files2.jpg │ │ ├── bg_title.jpg │ │ ├── button_status.png │ │ ├── download.gif │ │ ├── progress.jpg │ │ ├── progress_bg.jpg │ │ ├── select_file1.jpg │ │ ├── select_file1_pressed.jpg │ │ ├── select_file1_rollover.jpg │ │ ├── table_header_bg.jpg │ │ ├── table_header_bg2.jpg │ │ ├── trash.gif │ │ └── trash_white.png │ │ ├── index.html │ │ └── scripts │ │ ├── ajaxfileupload.js │ │ ├── bitcandies.upload5.js │ │ ├── jquery-1.7.2.min.js │ │ ├── lang.zh-Hans.js │ │ └── transfer.js │ ├── java │ └── com │ │ └── baidusoso │ │ └── wifitransfer │ │ ├── Constants.java │ │ ├── MainActivity.java │ │ ├── PopupMenuDialog.java │ │ ├── WebService.java │ │ ├── WifiConnectChangedReceiver.java │ │ └── WifiUtils.java │ └── res │ ├── anim │ ├── popup_menu_dialog_in.xml │ └── popup_menu_dialog_out.xml │ ├── drawable │ ├── ic_book_cover.png │ ├── ic_wifi.png │ ├── popup_menu_view_background.9.png │ ├── shared_wifi_enable.png │ └── shared_wifi_shut_down.png │ ├── layout │ ├── activity_main.xml │ ├── content_main.xml │ ├── layout_book_item.xml │ └── layout_popup_menu_dialog.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-v21 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── screenshot ├── phone1.png ├── phone2.png ├── phone3.png └── web.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 46 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WIFI传书 2 | 3 | 参照《多看》的WIFI传书功能 4 | * 手机端的HttpServer采用开源项目[AndroidAsync](https://github.com/koush/AndroidAsync)实现的。 5 | * 网页端采用jQuery实现,文件上传采用[Upload5](https://github.com/looptribe/upload5)(HTML5浏览器)和ajaxupload.js(非HTML5浏览器,如IE7/IE8/IE9) 6 | 7 | ## 手机端截图 8 | 9 | 10 | 11 | 12 | 13 | 14 | ## 网页版截图 15 | 16 | ## AndroidAsync HttpServer技术要点 17 | [AndroidAsync](https://github.com/koush/AndroidAsync)针对HTTP Servers模块的文档介绍非常少,需要大家自己去看源码。本项目中HTTP server功能都在[WebService.java](./app/src/main/java/com/baidusoso/wifitransfer/WebService.java)这个文件中。下面简单说一下本项目中用到一些传输API: 18 | 19 | * 获取x-www-form-urlencoded请求体 20 | 21 | ```java 22 | UrlEncodedFormBody body = (UrlEncodedFormBody) request.getBody(); 23 | ``` 24 | * 获取multipart/form-data请求体 25 | 26 | ```java 27 | MultipartFormDataBody body = (MultipartFormDataBody) request.getBody() 28 | ``` 29 | 30 | * 发送文本 31 | 32 | ```java 33 | response.send("Hello world!"); 34 | ``` 35 | 36 | * 发送文件流 37 | 38 | ```java 39 | BufferedInputStream bInputStream = ... 40 | response.sendStream(bInputStream, bInputStream.available()); 41 | response.sendFile(...); 42 | ``` 43 | 44 | * 发送Json 45 | 46 | ```java 47 | response.send(new JSONObject()); 48 | ``` 49 | 50 | * 发送Header 51 | 52 | ```java 53 | response.getHeaders().add("Content-Disposition", "attachment;filename=" + URLEncoder.encode(file.getName(), "utf-8")); 54 | ``` 55 | 56 | * 发送特定的响应码 57 | 58 | ```java 59 | response.code(500);//这个一定要和send()或者end()一起使用 60 | ``` 61 | 62 | ## WIFI传输 HttpServer文件上传功能实现 63 | 64 | ```java 65 | server.post("/files", (AsyncHttpServerRequest request, AsyncHttpServerResponse response) -> { 66 | final MultipartFormDataBody body = (MultipartFormDataBody) request.getBody(); 67 | body.setMultipartCallback((Part part) -> { 68 | if (part.isFile()) { 69 | body.setDataCallback((DataEmitter emitter, ByteBufferList bb) -> { 70 | fileUploadHolder.write(bb.getAllByteArray()); 71 | bb.recycle(); 72 | }); 73 | } else { 74 | if (body.getDataCallback() == null) { 75 | body.setDataCallback((DataEmitter emitter, ByteBufferList bb) -> { 76 | try { 77 | String fileName = URLDecoder.decode(new String(bb.getAllByteArray()), "UTF-8"); 78 | fileUploadHolder.setFileName(fileName); 79 | } catch (UnsupportedEncodingException e) { 80 | e.printStackTrace(); 81 | } 82 | bb.recycle(); 83 | }); 84 | } 85 | } 86 | }); 87 | request.setEndCallback((Exception e) -> { 88 | fileUploadHolder.reset(); 89 | response.end(); 90 | RxBus.get().post(Constants.RxBusEventType.LOAD_BOOK_LIST, 0); 91 | }); 92 | } 93 | ); 94 | ``` 95 | 96 | * 这里上传有2个Part:一个文件名,另一个是文件内容。之所以用有文件名Part是为了支持中文文件名:在multipart/form-data上传文件所存的中文文件名会因为AndroidAsync采用ASCII编码导致乱码。因此新增一个文件名Part,内容是网页端JS对文件名进行encodeURL,Server端拿到后再URLDecoder.decode得到中文文件名。 97 | 98 | * 这里涉及3个Callback:MultipartCallback、DataCallback和CompletedCallback。AndroidAsync采用NIO,处理请求体时候:每处理一个新的Part会回调MultipartCallback;通过多次回调DataCallback来接收文件内容;处理完所有的请求体回调CompletedCallback表示请求数据都已接收完毕,可以向客户端发送响应,如response.end()结束请求。 99 | 100 | ## TODO 101 | 因AndroidAsync采用NIO,目前还不知道怎么获取上传文件的大小。在使用非HTML5浏览器(如IE7/IE8/IE9)时候,文件上传进度无法正确显示。 102 | 103 | ## 版权声明 104 | 本项目参考《多看》实现的,网页端的资源于《多看》并稍作修改,不得用于任何商业用途,仅供学习研究使用,否则后果自负。 105 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'android-apt' 3 | apply plugin: 'me.tatarka.retrolambda' 4 | android { 5 | compileSdkVersion rootProject.ext.compileSdkVersion 6 | buildToolsVersion rootProject.ext.buildToolsVersion 7 | 8 | defaultConfig { 9 | minSdkVersion rootProject.ext.minSdkVersion 10 | targetSdkVersion rootProject.ext.targetSdkVersion 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | compileOptions { 15 | sourceCompatibility rootProject.ext.sourceCompatibilityVersion 16 | targetCompatibility rootProject.ext.targetCompatibilityVersion 17 | } 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | } 25 | 26 | dependencies { 27 | compile fileTree(dir: 'libs', include: "*.jar") 28 | compile deps.supportAppCompat 29 | compile deps.supportDesign 30 | compile deps.butterknife 31 | apt deps.butterknifeCompiler 32 | // compile deps.retrofit2 33 | // compile deps.rxjava 34 | // compile deps.converterGson 35 | // compile deps.adapterRxjava 36 | // compile deps.rxandroid 37 | compile(deps.rxbus) { 38 | exclude group: 'com.jakewharton.timber', module: 'timber' 39 | } 40 | compile deps.androidasync 41 | compile deps.timber 42 | } 43 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\program\AndroidSdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 17 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/assets/wifi/css/style.css: -------------------------------------------------------------------------------- 1 | html { margin: 0px; padding: 0px; overflow: visible; } 2 | body { background-image: url('../images/bg1_01.jpg'); padding: 0px;margin: 0px; overflow: hidden; font-size: 14px; font-family:tahoma, 宋体, Arial, "MS Trebuchet", sans-serif;}/*background-image: url('../images/bg1_02.jpg');background-color: #376cab;*/ 3 | #wrapper { height: 768px; } 4 | #content { margin: 0px auto 0px auto; width:950px; height:768px; position: relative; } 5 | #left { margin: 0px 0px 0px 50px; } 6 | #logo { position: relative; height:417; } 7 | #logo .wifi { position:absolute;font-size:48px; line-height:48px; color:#ffffff; text-align:center; top:10px; } 8 | .hint { font-size: 12px; color: #FFF; width:243px; height:30px; text-align: center; line-height:15px; } 9 | #upload_form { position:absolute;left:50px;top:400px; } 10 | .file_upload_warper { position: absolute; top:0px; left:0px; width:212px; height:92px; overflow: hidden; } 11 | .file_upload { cursor: pointer; position: absolute; top:0px; left:-250px; width:500px; height:500px;font-size: 500px; opacity: 0; -moz-opacity: 0; filter:alpha(opacity=0); } 12 | #copyright { margin-top: 170px; font-size: 14px; color: #FFF; width:243px; text-align: center; } 13 | #right_wrapper { background-image: url('../images/bg_files2.jpg'); background-repeat: repeat-y; width:559px; height:5000px;position: absolute;top: 0px; left:350px } 14 | #right { background-image: url('../images/bg_files.jpg'); background-repeat: no-repeat; height:100%; width:100%; } 15 | #right .content_title { margin-left:37px;width:483px; height:40px; background-color: #96abbe; background-image: url('../images/bg_title.jpg'); line-height:40px;text-indent: 10px; font-size:14px; color:#FFFFFF;border-bottom: 1px solid #87a2b8; } 16 | #right .content_title .drag_hint { padding-left:10px; font-size:12px; color:#FFCC00 } 17 | #right .table_header { margin-left:37px;width:483px; height:34px; background-image: url('../images/table_header_bg2.jpg'); border-bottom: 1px solid #bac8d2; } 18 | #right .table_header .separator { background-image: url('../images/table_header_bg.jpg'); background-repeat: no-repeat; } 19 | #right .table_header .column { text-indent: 10px; float: left; height:34px; line-height:34px; color:#607589; font-size:12px } 20 | #right .table_header .filename { width:313px; } 21 | #right .table_header .size { width:80px; } 22 | #right .table_header .operate { width:80px; text-align:center; } 23 | #right .files { background-image: url('../images/bg_file_list.jpg'); margin-left:37px; width:483px; overflow: auto;} 24 | #right .file { line-height:40px; height:40px; line-height:40px; color:#000; font-size:12px; position: relative; } 25 | #right .progress_wrapper { color:#FFF; background-image: url('../images/progress_bg.jpg'); background-repeat: repeat-x;} 26 | #right .progress { position: absolute; top:0px; left:0px; height: 40px; width: 0px; background-image: url('../images/progress.jpg'); background-repeat: repeat-x; z-index: 1; } 27 | #right .files .even { background-color: #dadfe4; } 28 | #right .files .column { position:relative; text-indent: 10px; float: left; height:40px; overflow: hidden; z-index:2; } 29 | #right .files .filename { width:313px; } 30 | #right .files .size { width:80px; } 31 | #right .files .precent { width:44px; text-align:right;} 32 | #right .files .trash { margin-left: 0px; width:20px; height:40px; background-position: center; background-repeat: no-repeat; background-image: url('../images/trash.gif'); cursor: pointer; } 33 | #right .files .trash_white { margin-left: 0px; width:20px; height:40px; background-position: center; background-repeat: no-repeat; background-image: url('../images/trash_white.png'); cursor: pointer; } 34 | #right .files .download { margin-left: 0px; width:44px; height:40px; background-position: right; background-repeat: no-repeat; background-image: url('../images/download.gif'); cursor: pointer; } 35 | 36 | #drag_area { position:absolute;left:0;top:200px;width:180px; height:180px; margin-left:30px; background-image: url("../images/bg_drag.png"); background-repeat:no-repeat; } 37 | #drag_area.normal { background-position: 0px 0px; } 38 | #drag_area.active { background-position: 0px -181px; } 39 | 40 | #upload_button { width:210px; height:90px; margin-left: 17px; background-image: url("../images/button_status.png");background-repeat:no-repeat; } 41 | #upload_button.normal { background-position: 0px 0px; } 42 | #upload_button.pressed { background-position: 0px -91px; } 43 | #upload_button.rollover { background-position: 0px -182px; } 44 | 45 | #drag_area .drag_hint { font-size:20px; text-shadow:0px 4px 4px rgba(0,0,0,0.4); color:#ffffff; text-align: center; padding-top:130px; -moz-user-select: none;-khtml-user-select: none; user-select: none; } 46 | .button_lables { position: absolute; top:26px; left:0px; width:212px; height:92px; } 47 | .button_lables .button_lable1 {font-size:18px; line-height:18px; color:#ffffff; text-align:center; -moz-user-select: none;-khtml-user-select: none; user-select: none;} 48 | .button_lables .button_lable2 {font-size:12px; line-height:16px; color:#ffffff; text-align:center; -moz-user-select: none;-khtml-user-select: none; user-select: none;} 49 | .button_lable { position: absolute; width:210px; height:90px; font-size:20px; line-height:80px; color:#ffffff; text-align:center;} -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/bg1_01.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/bg1_01.jpg -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/bg1_02.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/bg1_02.jpg -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/bg_drag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/bg_drag.png -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/bg_file_list.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/bg_file_list.jpg -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/bg_files.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/bg_files.jpg -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/bg_files2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/bg_files2.jpg -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/bg_title.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/bg_title.jpg -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/button_status.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/button_status.png -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/download.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/download.gif -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/progress.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/progress.jpg -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/progress_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/progress_bg.jpg -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/select_file1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/select_file1.jpg -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/select_file1_pressed.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/select_file1_pressed.jpg -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/select_file1_rollover.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/select_file1_rollover.jpg -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/table_header_bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/table_header_bg.jpg -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/table_header_bg2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/table_header_bg2.jpg -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/trash.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/trash.gif -------------------------------------------------------------------------------- /app/src/main/assets/wifi/images/trash_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/baidusoso/WifiTransfer/0c0fc9f22dfac425d15b2447b71f2ff7ae6596ee/app/src/main/assets/wifi/images/trash_white.png -------------------------------------------------------------------------------- /app/src/main/assets/wifi/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | WiFi 传书 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 | 19 |
20 |
21 |
22 |
23 | 24 |
25 |
26 | 27 |
28 |
29 | 39 |
40 |
41 |
42 | 43 | -------------------------------------------------------------------------------- /app/src/main/assets/wifi/scripts/ajaxfileupload.js: -------------------------------------------------------------------------------- 1 | 2 | jQuery.extend({ 3 | 4 | 5 | createUploadIframe: function(id, uri) 6 | { 7 | //create frame 8 | var frameId = 'jUploadFrame' + id; 9 | var iframeHtml = '