jqに基づいてAPKファイルのドラッグアップロードを実現し、jsはAPK情報を解析する
13785 ワード
テクノロジースタック jquery ファイルアップロード:jquery.file upload,githubドキュメント apkファイル解析:app-info-parser,githubドキュメント 参考:フロントエンド解析ipa、apkインストールパッケージ情報-app-info-parser
サポート機能クリックまたはドラッグアップロードapkファイル ファイルタイプおよびファイルサイズのチェック js解析apkファイル情報は、アップロードインタフェースを介してバックエンド に送信する.はアップロード中に のアップロードをキャンセルすることをサポートする.アップロード成功表示アップロード情報 をサポートは解析、アップロードなどの友好的なヒント をサポートする.は、履歴(アップロードされたすべてのファイル)から を選択することをサポートします.は、例えば、偽ファイル処理をサポートする.txtファイルを.apkファイル アップロードの進捗状況のリアルタイム更新、パーセント、B/s ドラッグしてドラッグエリアに入ると、 がハイライト表示されます.
demoプレビュー
説明
アップロードインタフェースにはバックエンドインタフェースのサポートが必要なため、静的ページで完全なインタラクションを表示することはできません.そこで、ここにプレビュー図を置きます.
gif図が大きすぎるのを避けるために、クリックアップロードに成功した場合だけを録画しました.他の状況はスクリーンを録画していないので、自分でdemoをダウンロードして、バックエンド環境を構築して、アップロードインタフェースをシミュレートして実現することができます.demoではphp言語シミュレーションでアップロードインタフェースを実現した.ソースアドレス
難点 js解析APKファイル情報 ドラッグアップロード、クリックアップロードとドラッグアップロードバインド アップロードする前にAPKファイル情報を知らないため、アップロード操作を実行する過程で解析したファイル情報をパラメータとしてアップロードインタフェースに配置する必要がある .アップロード中に アップロードをキャンセル偽ファイル解析エラー処理、jsモニタコンソールエラー インプリメンテーション
1.js解析APKファイル情報
調べたところ、APKファイルの本質は圧縮パッケージであり、XMLファイル、資産、クラスファイルの山が含まれていることがわかりました.JAvascriptはAPKファイル情報を解析し、まず解凍し、その中の関連ファイルを読み取ることで、ファイル情報を得ることができます.
難点は解凍で、参考の基本はnode環境を借りる必要があります.現在メンテナンスされているシステムはjquery環境に基づいているためです.そこで,最終的にipa,apkインストールパッケージ情報であるapp-info-parserをフロントエンド解析するスキームを採用し,問題をうまく解決した.ここで著者に感謝します.
説明: app-info-parserの下位層がasync構文を使用しているため、IEの下では互換性がありません.firefox、chromeでは正常です. 偽APKファイルをアップロードし、処理できません.jsスクリプトはエラーを報告します:
ページの他のエラーを回避するために、スクリプトが実行できないため、ページのリフレッシュを行いました.
2.ドラッグアップロード、クリックアップロードとドラッグアップロードを一緒にバインド
この機能を行う前に、ドラッグアップロードはH 5のドラッグアップ機能やオリジナルjsのfileファイルアップロードで実現できると思いますが、互換性の問題を処理する必要があります.その後、システムにjqueryが導入されたと考えられた.file uploadライブラリは、ドキュメントをめくってドラッグアップロードをサポートしています.そのため、このライブラリを使用してドラッグアップロード機能を実現します.
htmlレイアウトは次のとおりです.
どのようにドラッグ&ドロップを一緒に処理して、1つのアップロード方法で実現して、別々に2回実現する必要はありませんか?
考えは,外層コンテナをクリックし,inputクリックイベントをトリガーすることである.前提はinputクリックイベントを実現し、外層にもクリックイベントがあるため、バブルイベントを阻止する必要がある.
ドラッグしてハイライトに入り、リカバリから遠ざかることができます.
ケースの再現:偽の内容が空のapkファイルをクリックすると、ファイルサイズが間違っていることがヒントになります. このとき、2回目のクリックではinputのクリックイベントをトリガーできません.何度も繰り返しても無効です. このとき、ドラッグアップロードにより正常に実行できるが、2回のアップロード処理がトリガーされ、2回のファイルが解析され、2回のアップロードインタフェース要求が送信される.
3.アップロードする前にAPKファイル情報を知らない場合、アップロード操作を実行して解析したファイル情報をパラメータとしてアップロードインタフェースに入れる必要がある
以前に作成したアップロードは、アップロード前にアップロード時にコミットする必要がある追加のパラメータ値を知っていました.
しかし、現在では、アップロード前にパラメータ値が分からないため、アップロード操作を実行し、アップロードファイル情報を取得し、アップロードファイルの情報を解析し、解析情報をパラメータ値としてアップロード要求に格納する必要がある.どうすればいいですか.長い間研究して、やっと見つけました.
4.アップロード中にアップロードをキャンセルする
これは比較的簡単です.アップロードコール中の
5.ファイルアップロードの主なコード
php環境の簡単な構築 xampp統合環境パッケージをダウンロードして をインストール demoプロジェクトの解凍コピーがインストールディレクトリのhtdocsにコピーされたディレクトリの下で、私のディレクトリは です. phpアップロードに制限があるため、ファイル ps:PHPアップロードサイズ制限 参照
最後にインストールディレクトリの下( 開く.ブラウザウィンドウ入力 demo効果 を完全に表示ソースアドレス
サポート機能
demoプレビュー
説明
アップロードインタフェースにはバックエンドインタフェースのサポートが必要なため、静的ページで完全なインタラクションを表示することはできません.そこで、ここにプレビュー図を置きます.
gif図が大きすぎるのを避けるために、クリックアップロードに成功した場合だけを録画しました.他の状況はスクリーンを録画していないので、自分でdemoをダウンロードして、バックエンド環境を構築して、アップロードインタフェースをシミュレートして実現することができます.demoではphp言語シミュレーションでアップロードインタフェースを実現した.ソースアドレス
難点
1.js解析APKファイル情報
調べたところ、APKファイルの本質は圧縮パッケージであり、XMLファイル、資産、クラスファイルの山が含まれていることがわかりました.JAvascriptはAPKファイル情報を解析し、まず解凍し、その中の関連ファイルを読み取ることで、ファイル情報を得ることができます.
難点は解凍で、参考の基本はnode環境を借りる必要があります.現在メンテナンスされているシステムはjquery環境に基づいているためです.そこで,最終的にipa,apkインストールパッケージ情報であるapp-info-parserをフロントエンド解析するスキームを採用し,問題をうまく解決した.ここで著者に感謝します.
// apk
var parser = new AppInfoParser(data.files[0]);
parser.parse().then(function(result) {
uploadMod.doms.uploadErr.html('');
var appInfo = result.application || {};
var formAppInfo = {
name: appInfo.label ? (Array.isArray(appInfo.label) ? appInfo.label[0] : appInfo.label) : '',
package: result.package,
version: result.versionName,
version_code: result.versionCode
};
// ...
}).catch(function (err) {
uploadMod.doms.uploadErr.html(' , ');
});
説明:
File format is not recognized.
.現在考えられている解決策はjsがエラーを傍受し、処理することである.もっといい考えがあれば、@私を歓迎します.ここで前もって感謝します.// console.error()
consoleError = window.console.error;
window.console.error = function () {
consoleError && consoleError.apply(window, arguments);
for (var info in arguments) {
if (arguments[info] == 'File format is not recognized.') {
$('#app_parse').html(' APK , , , ,
');
setTimeout(function () {
history.go(0);
}, 3000);
return false;
}
}
};
ページの他のエラーを回避するために、スクリプトが実行できないため、ページのリフレッシュを行いました.
2.ドラッグアップロード、クリックアップロードとドラッグアップロードを一緒にバインド
この機能を行う前に、ドラッグアップロードはH 5のドラッグアップ機能やオリジナルjsのfileファイルアップロードで実現できると思いますが、互換性の問題を処理する必要があります.その後、システムにjqueryが導入されたと考えられた.file uploadライブラリは、ドキュメントをめくってドラッグアップロードをサポートしています.そのため、このライブラリを使用してドラッグアップロード機能を実現します.
htmlレイアウトは次のとおりです.
APK , 300 MB
どのようにドラッグ&ドロップを一緒に処理して、1つのアップロード方法で実現して、別々に2回実現する必要はありませんか?
考えは,外層コンテナをクリックし,inputクリックイベントをトリガーすることである.前提はinputクリックイベントを実現し、外層にもクリックイベントがあるため、バブルイベントを阻止する必要がある.
$('body').on('click', '#upload_input', function (e) {
e.stopPropagation();
uploadMod.methods.fileUpload();
}).on('click drop dragenter dragover dragleave', '#upload_area', function(e) {
e.preventDefault();
uploadMod.doms.uploadErr.html('');
switch (e.type) {
case 'click':
$('#upload_input').val(null);
$('#upload_input').click();
break;
case 'drop':
uploadMod.doms.uploadArea.removeClass('active');
$('#upload_input').val(null);
uploadMod.methods.fileUpload();
break;
case 'dragenter':
case 'dragover':
uploadMod.doms.uploadArea.addClass('active');
break;
case 'dragleave':
uploadMod.doms.uploadArea.removeClass('active');
break;
}
})
ドラッグしてハイライトに入り、リカバリから遠ざかることができます.
$('#upload_input')
は、キャッシュされた変数を使用できないことに注意してください.二次クリックアップロードが無効になり、クリックをトリガーしてファイルウィンドウを開くことができません.また、この時点で正しいファイルをドラッグしてアップロードすると、2回のファイルアップロードがトリガーされます.アップロードインタフェースを2回送信します.興味のある方は自分でキャッシュを使ってみてください.ケースの再現:
3.アップロードする前にAPKファイル情報を知らない場合、アップロード操作を実行して解析したファイル情報をパラメータとしてアップロードインタフェースに入れる必要がある
以前に作成したアップロードは、アップロード前にアップロード時にコミットする必要がある追加のパラメータ値を知っていました.
$('#upload_input').fileupload({
url: 'http://localhost:80/jq-drag-upload-apk-parse/upload.php',
dataType: 'json',
formData: params, // params js ,
multi: false,
// ....
})
しかし、現在では、アップロード前にパラメータ値が分からないため、アップロード操作を実行し、アップロードファイル情報を取得し、アップロードファイルの情報を解析し、解析情報をパラメータ値としてアップロード要求に格納する必要がある.どうすればいいですか.長い間研究して、やっと見つけました.
$('#upload_input').fileupload({
url: 'http://localhost:80/jq-drag-upload-apk-parse/upload.php',
dataType: 'json',
formData: params, // params js ,
multi: false,
add: function (e, data) {
//
// APK UI
$(e.target).fileupload(
'option',
'formData',
formAppInfo // APK
);
data.submit();
},
// ....
})
4.アップロード中にアップロードをキャンセルする
これは比較的簡単です.アップロードコール中の
data.abort()
で実現できます.処理する必要があるのは,add()メソッドではまず外層にdataをキャッシュしてから呼び出しを容易にする必要がある.$('#upload_input').fileupload({
url: 'http://localhost:80/jq-drag-upload-apk-parse/upload.php',
dataType: 'json',
formData: params, // params js ,
multi: false,
add: function (e, data) {
//
// APK UI
// ,
uploadMod.uploadXHR = data;
$(e.target).fileupload(
'option',
'formData',
formAppInfo // APK
);
data.submit();
},
fail: function(e, data) {
if (data.errorThrown == 'abort') {
uploadMod.doms.uploadErr.html(' , ');
} else {
uploadMod.doms.uploadErr.html(' , ');
}
},
// ....
})
$('body').on('click', '#upload_cancel', function () {
uploadMod.uploadXHR.abort();
})
5.ファイルアップロードの主なコード
fileCheck: function(e, data) {
//
var acceptFileTypes = uploadMod.doms.uploadInput.attr('accept');
var supportFileTypes = ['apk']; // name , type
var maxSize = uploadMod.doms.uploadInput.data('size') * 1024 * 1024; // mb, b
var fileTypeFlag = data.originalFiles.every(function(item) {
if (item.type) {
return acceptFileTypes.indexOf(item.type) > -1;
} else {
var splits = (item.name || file).split('.');
var fileType = splits[splits.length - 1];
return supportFileTypes.indexOf(fileType) > -1;
}
});
if (!fileTypeFlag) {
uploadMod.doms.uploadErr.html(' APK ');
return false;
}
var fileSizeFlag = data.originalFiles.every(function(item) {
return item.size > 0 && item.size <= maxSize;
});
if (!fileSizeFlag) {
data = {};
uploadMod.doms.uploadErr.html(' ');
return false;
}
uploadMod.doms.progressWrap.show();
var $appParse = uploadMod.doms.progressWrap.find('.app-parse'),
$progressCon = uploadMod.doms.progressWrap.find('.con');
$appParse.show();
$progressCon.hide();
// apk
var parser = new AppInfoParser(data.files[0]);
parser.parse().then(function(result) {
uploadMod.doms.uploadErr.html('');
var appInfo = result.application || {};
var formAppInfo = {
name: appInfo.label ? (Array.isArray(appInfo.label) ? appInfo.label[0] : appInfo.label) : '',
package: result.package,
version: result.versionName,
version_code: result.versionCode
};
//
$appParse.hide();
$progressCon.show();
if (result.icon) {
uploadMod.doms.progressWrap.find('.icon-app').css('background-image', 'url("' + result.icon + '")');
}
uploadMod.doms.progressWrap.find('.name').html(formAppInfo.name);
uploadMod.doms.progressWrap.find('.package').html(formAppInfo.package);
uploadMod.doms.progressWrap.find('.version').html(formAppInfo.version);
uploadMod.doms.progressWrap.find('.version-code').html(formAppInfo.version_code);
uploadMod.doms.progressWrap.find('.progress').css('width', 0);
uploadMod.doms.progressWrap.find('.num').html(0);
uploadMod.doms.progressWrap.find('.size').html(0);
//
uploadMod.uploadXHR = data;
$(e.target).fileupload(
'option',
'formData',
formAppInfo
);
data.submit();
}).catch(function (err) {
uploadMod.doms.progressWrap.hide();
uploadMod.doms.uploadErr.html(' , ');
data.abort();
});
// console.error()
consoleError = window.console.error;
window.console.error = function () {
consoleError && consoleError.apply(window, arguments);
for (var info in arguments) {
if (arguments[info] == 'File format is not recognized.') {
$('#app_parse').html(' APK , , , ,
');
setTimeout(function () {
history.go(0);
}, 3000);
return false;
}
}
};
},
fileUpload: function(el) {
$('#upload_input').fileupload({
url: 'http://localhost:80/jq-drag-upload-apk-parse/upload.php',
dataType: 'json',
multi: false,
add: uploadMod.methods.fileCheck,
paste: function () { return false; },
done: function(e, data) { //
var result = data.result;
if (result && result.flag && result.data) {
uploadMod.doms.uploadErr.html(result.msg || ' ');
uploadMod.data.selectedAPK = result.data;
uploadMod.methods.renderHistory(result.data);
} else {
uploadMod.doms.progressWrap.hide();
uploadMod.doms.uploadErr.html(result.msg || ' ');
}
},
fail: function(e, data) {
if (data.errorThrown == 'abort') {
uploadMod.doms.uploadErr.html(' , ');
} else {
uploadMod.doms.uploadErr.html(' , ');
}
},
progressall: function(e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
uploadMod.doms.progressWrap.find('.progress').css('width', progress + '%');
uploadMod.doms.progressWrap.find('.num').html(progress);
uploadMod.doms.progressWrap.find('.size').html(bytesToSize(data.bitrate));
function bytesToSize(bit) {
if (bit === 0) return '0 B';
var bytes = bit / 8;
var k = 1024,
sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
i = Math.floor(Math.log(bytes) / Math.log(k));
return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
}
}
})
},
php環境の簡単な構築
C:\xampp\htdocs\jq-drag-upload-apk-parse
C:\xampp\php\php.ini
を変更する必要があります.変更する必要がある点:max_execution_time = 0
、デフォルト30秒、0は無制限post_max_size = 500M
、デフォルト2 M upload_max_filesize = 100M
、デフォルト8 M C:\xampp
)のxamppをクリックする.control.exeはインタフェースを開き、オープンインタフェースでApache対応Actionsをhttp://localhost/jq-drag-upload-apk-parse/index.html