⏺MySQL 使用 Shell 指令快速上傳資料庫
◆ MariaDB (有些功能與 MySQL 共用)
OS:Debian 8.11
Apache:2.4.6
DB:MySQL 5.5.62
PHP: 5.5.40
----------------------------------------------------
用這種方式速度比phpMyAdmin更快,能容許的檔案更大。當然要注意當初備份下載時所設定的參數(下載設定),小心當初設定參數不良,把現有資料庫中同名的 DB 刪除。
語法看下圖紅框處,
程式碼:
<!DOCTYPE html>
<html lang=zh-Hant>
<head>
<title>preview picture with no bootstrap no jQuery</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<style>
#OriginInput{
border:1px solid red;
height:30px;
opacity:100; /* 必須為 0,覆蓋的「綠色圖片按鈕」才有作用 */
width:90px;
cursor:pointer;
}
#click_me{/*這是圖片,來當覆蓋按鈕*/
margin-top:0px;
margin-left:-60px;
opacity:100; /* 0:不顯示 */
/* cursor:pointer; 没作用,被 #OriginInput 強制取代 */
}
</style>
<body>
(1) 三種方式取得上傳圖片資料:二進位碼字串、UTF-8字串、Base64編碼字串。<br />
(2) 上傳圖檔絕對路徑不正確,基本是瀏覽器之安全設定問題<br />
(3) 綠色圖片游標變手型時,點按可上傳圖檔 但CSS要先設定 OriginInput.opacity = 0<br />
(4) 預覽圖片可依需求動態調整大小<br />
(5) 本程式已有多檔上傳功能,略改寫就能達到<br />
<br />
<div id="result" style="border:1px solid red;">測試結果區</div>
<form action="後台程式名.php" method="post" enctype="multipart/form-data">
<input id="PretendInput" type="text" readonly >
<input id="OriginInput" type="file" multiple accept="image/gif, image/jpeg, image/png" onchange="setFilePath()" >
<img id="click_me" src="https://via.placeholder.com/100x35/00FF00/" ><br />
</form>
</body>
<script>
function setFilePath(){
//--- 取得單一檔案路徑 + 檔名 - 第1種正確 =>
var oOriginInput=document.getElementById("OriginInput");
var oFiles=document.getElementById("OriginInput").files[0];
if(oFiles && oFiles.name.trim().length > 4){
let reader = new FileReader();
/*
//-- 開始:用二進位字串顯示圖片資料 (讀出圖片16進位資料)
reader.readAsBinaryString(oFiles);
reader.onload = function(e) {
let vData = e.target.result;
document.getElementById("result").innerHTML = null;
document.getElementById("result").innerHTML = vData;
};
//-- 結束
*/
/*
//-- 開始:用UTF-8字串顯示圖片資料 (讀出圖片16進位資料,呈現很多都無字型碼)
reader.readAsText(oFiles,'UTF-8');
reader.onload = function (e) {
let vData = e.target.result;
document.getElementById("result").innerHTML = null;
document.getElementById("result").innerHTML = vData;
};
//-- 結束
*/
//-- 開始:解譯Base64編碼,直接預覽圖片 (讀出圖片16進位資料)
reader.readAsDataURL(oFiles);
reader.onload = function (e) {
let vData = e.target.result;
//let vData = document.getElementById("OriginInput").result; <= 錯誤語法
//說明:(1) e.target == document.getElementById("OriginInput"), 但是 input
// 没有 result 屬性。
// (2) 判斷 e.target 應該是最早取得結果值的物件,而 OriginInput 則是較後期才
// 取得上傳的資料(或由e.target 把部份值塞給 OriginInput 的屬性變數)。
//塞入完整「檔案路徑 + 檔名」
document.getElementById("PretendInput").value=oOriginInput.value;
//預覽檔名
document.getElementById("result").innerHTML =null;
document.getElementById("result").innerHTML =oFiles.name + " <br /> ";
//預覽圖片 (以下這段程式中的 vData 資料不是字串,是base64之圖片編碼)
document.getElementById("result").innerHTML += "<img src='" + vData + "' style='width:120px;height:120px;' alt='" + oFiles.name + "' />";
};
//-- 結束
}else{
document.getElementById("PretendInput").value="";
}
/*
//--- 第2種 -- 取得單一「檔案路徑 + 檔名」之結果不正確 => C:\fakepath\sa.png
var oFilePath=document.getElementById("OriginInput");
if(oFilePath.value.trim().length > 0){
document.getElementById("PretendInput").value=oFilePath.value;
alert("取得檔案路徑及檔名:" + oFilePath.value);
}else{
document.getElementById("PretendInput").value="";
}
*/
/*
//--- 取得檔案名稱(適合多檔上傳架構)
var oFiles=document.getElementById("OriginInput").files;
var j=oFiles.length;
//console.log("共 " + j + " 個檔名");
for(let i=0;i<j;i++){
if (oFiles[i]){
//alert("取得第 " + parseInt(i+1) + " 個檔名:" + oFiles[i].name.trim());
//以下三個有反應
console.log("取得第 " + parseInt(i+1) + " 個 name:" + oFiles[i].name.trim());
console.log("取得第 " + parseInt(i+1) + " 個 type:" + oFiles[i].type.trim());
console.log("取得第 " + parseInt(i+1) + " 個 size:" + oFiles[i].size);
//以下二個 undefined
console.log("取得第 " + parseInt(i+1) + " 個 tmp_name:" + oFiles[i].tmp_name);
console.log("取得第 " + parseInt(i+1) + " 個 error:" + oFiles[i].error);
}
}
*/
/*
//--- 取得檔案名稱(適合單檔上傳架構)
var oFiles=document.getElementById("OriginInput").files;
//if(oFiles && oFiles.length>0 && sFileName.length > 0){
if(oFiles){
let sFileName=oFiles[0].name.trim();
document.getElementById("PretendInput").value=sFileName;
alert("取得檔案名稱:" + sFileName);
}else{//清空檔名
document.getElementById("PretendInput").value="";
}
*/
}
</script>
</html>
<!DOCTYPE html>
<html lang=zh-Hant>
<head>
<title>picture upload with bootstrap and jQuery</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" rel="stylesheet" type="text/css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" ></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" ></script>
</head>
<style>
.image-preview-wrapper{
display: block;
max-width: 310px;
max-height: 310px;
width: 100%;
border: 2px solid #cccccc;
margin: 0 auto;
position: relative;
cursor: pointer;
}
.spinner-wrapper {
opacity: 0;
margin: 0;
padding: 0;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
.opacity-1 {
opacity: 1;
}
#idSubmit{
cursor:pointer;
}
#file-uploader, #idFilePath{
cursor:pointer;
}
</style>
<body>
<br /><br />
<div class="row">
<div class="col-12 col-md-6 mx-auto">
<a style="float:left" href="https://pjchender.blogspot.com/2019/01/js-javascript-input-file-upload-file.html">程式來源</a>
</div></div>
<br /><br />
<label class="text-center mb-5 image-preview-wrapper" for="file-uploader">
<img src="https://via.placeholder.com/500x300?text=click to upload" alt="image-placehoder" class="img-thumbnail" data-target="image-preview">
<!-- loading --->
<div class="spinner-wrapper position-absolute" data-target="spinner">
<div class="spinner-border text-secondary" role="status">
<span class="sr-only">Loading...</span>
</div>
</div>
</label>
<div class="row">
<div class="col-12 col-md-6 mx-auto">
<div class="custom-file">
<form action="後台程式名.php" method="post" enctype="multipart/form-data">
<input type="file" class="custom-file-input" id="file-uploader" multiple accept="image/gif, image/jpeg, image/png" data-target="file-uploader" onchange="setFilePath()" >
<label class="custom-file-label" id="idFilePath">點按上傳檔案</label>
<br /><br />
<input type="submit" id="idSubmit" value="Submit">
</form>
</div>
</div>
</div>
</body>
<script>
function setFilePath(){
document.getElementById("idFilePath").innerText=document.getElementById("file-uploader").value;
}
</script>
<script>
// STEP 1: select element and register change event
const imagePreview = document.querySelector('[data-target="image-preview"]');
const spinner = document.querySelector('[data-target="spinner"]');
const fileUploader = document.querySelector('[data-target="file-uploader"]');
fileUploader.addEventListener("change", handleFileUpload);
async function handleFileUpload(e) {
try {
const file = e.target.files[0];
setUploading(true);
if (!file) return;
const beforeUploadCheck = await beforeUpload(file);
if (!beforeUploadCheck.isValid) throw beforeUploadCheck.errorMessages;
const arrayBuffer = await getArrayBuffer(file);
const response = await uploadFileAJAX(arrayBuffer);
alert("File Uploaded Success");
showPreviewImage(file);
} catch (error) {
alert(error);
console.log("Catch Error: ", error);
} finally {
e.target.value = ''; // reset input file
setUploading(false);
}
}
// STEP 2: showPreviewImage with createObjectURL
// If you prefer Base64 image, use "FileReader.readAsDataURL"
function showPreviewImage(fileObj) {
const image = URL.createObjectURL(fileObj);
imagePreview.src = image;
}
// STEP 3: change file object into ArrayBuffer
function getArrayBuffer(fileObj) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
// Get ArrayBuffer when FileReader on load
reader.addEventListener("load", () => {
resolve(reader.result);
});
// Get Error when FileReader on error
reader.addEventListener("error", () => {
reject("error occurred in getArrayBuffer");
});
// read the blob object as ArrayBuffer
// if you nedd Base64, use reader.readAsDataURL
reader.readAsArrayBuffer(fileObj);
});
}
// STEP 4: upload file throguth AJAX
// - use "new Uint8Array()"" to change ArrayBuffer into TypedArray
// - TypedArray is not a truely Array,
// use "Array.from()" to change it into Array
function uploadFileAJAX(arrayBuffer) {
// correct it to your own API endpoint
return fetch("https://jsonplaceholder.typicode.com/posts/", {
headers: {
version: 1,
"content-type": "application/json"
},
method: "POST",
body: JSON.stringify({
imageId: 1,
icon: Array.from(new Uint8Array(arrayBuffer))
})
})
.then(res => {
if (!res.ok) {
throw res.statusText;
}
return res.json();
})
.then(data => data)
.catch(err => console.log("err", err));
}
// STEP 5: Create before upload checker if needed
function beforeUpload(fileObject) {
return new Promise(resolve => {
const validFileTypes = ["image/jpeg", "image/png"];
const isValidFileType = validFileTypes.includes(fileObject.type);
let errorMessages = [];
if (!isValidFileType) {
errorMessages.push("You can only upload JPG or PNG file!");
}
const isValidFileSize = fileObject.size / 1024 / 1024 < 2;
if (!isValidFileSize) {
errorMessages.push("Image must smaller than 2MB!");
}
resolve({
isValid: isValidFileType && isValidFileSize,
errorMessages: errorMessages.join("\n")
});
});
}
function setUploading(isUploading) {
if (isUploading === true) {
spinner.classList.add("opacity-1");
} else {
spinner.classList.remove("opacity-1");
}
}
</script>
</html>