ufs-client-js
Version:
品高统一文件服务(UFS) JSSDK
357 lines (333 loc) • 9.52 kB
JavaScript
function _createAjax() {
var xmlhttp = {};
if (XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
} else {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlhttp;
}
// 如果ajax支持进度并且options指定了进度函数,附加进度事件回调
function attachUploadProgress(xhr, options) {
if (xhr.upload && options && options.onProgress) {
xhr.upload.onprogress = function progress(e) {
if (e.total > 0) {
e.percent = (e.loaded / e.total) * 100;
}
options.onProgress(e);
};
}
}
// 区分weex和web环境
export function fetchAdapter(url, options) {
options = Object.assign(
{
jsonParse: true,
responseType: "",
},
options
);
try {
//weex client ajax
if (weex) {
return new Promise((resolve, reject) => {
var stream = weex.requireModule("stream");
options.url = url;
stream.fetch(options, (res) => {
if (res.ok) {
if (typeof res.data == "string") {
res.data = JSON.parse(res.data);
}
resolve(res.data);
} else {
reject(res);
}
});
});
}
} catch (ex) {
// web client ajax
return new Promise((resolve, reject) => {
let xhr = _createAjax();
attachUploadProgress(xhr, options);
let method = options.method || "GET";
xhr.open(method, url);
if (options.headers) {
for (let key in options.headers) {
xhr.setRequestHeader(key, options.headers[key]);
}
}
xhr.responseType = options.responseType;
xhr.onreadystatechange = function () {
if (xhr.readyState != 4) {
return;
}
if (xhr.status == 200) {
let response = options.jsonParse
? JSON.parse(xhr.response)
: xhr.response;
resolve(response);
} else {
reject(xhr);
}
};
if (options.body) {
xhr.send(options.body);
} else {
xhr.send();
}
});
}
// default client ajax
return new Promise((resolve, reject) => {
let xhr = _createAjax();
attachUploadProgress(xhr, options);
let method = options.method || "GET";
xhr.open(method, url);
if (options.headers) {
for (let key in options.headers) {
xhr.setRequestHeader(key, options.headers[key]);
}
}
xhr.responseType = options.responseType;
xhr.onreadystatechange = function () {
if (xhr.readyState != 4) {
return;
}
if (xhr.status == 200) {
let response = options.jsonParse
? JSON.parse(xhr.response)
: xhr.response;
resolve(response);
} else {
reject(xhr);
}
};
if (options.body) {
xhr.send(options.body);
} else {
xhr.send();
}
});
}
export function uploadAdapter(url, options, fileObj) {
options = Object.assign({}, options);
try {
//weex client upload
if (weex) {
return new Promise((resolve, reject) => {
//用weex的方式上传文件
let fileTransfer = weex.requireModule("FileTransferModule");
fileTransfer.upload(
fileObj,
url,
{
headers: options.headers,
method: "PUT",
},
null,
(result) => {
resolve(result);
},
(err) => {
reject(err);
}
);
});
}
} catch (ex) {
//web client upload
return new Promise((resolve, reject) => {
if (isIOS() && isCordova()) {
iOSUpload(url, options, fileObj, resolve, reject);
return;
}
let xhr = _createAjax();
attachUploadProgress(xhr, options);
let method = options.method || "PUT";
xhr.open(method, url, true);
if (options.headers) {
for (let key in options.headers) {
xhr.setRequestHeader(key, options.headers[key]);
}
}
xhr.onreadystatechange = function () {
if (xhr.readyState != 4) {
return;
}
if (xhr.status == 200) {
resolve(xhr.response);
} else {
reject(xhr);
}
};
xhr.send(fileObj);
});
}
//default web client upload
return new Promise((resolve, reject) => {
if (isIOS() && isCordova()) {
iOSUpload(url, options, fileObj, resolve, reject);
return;
}
let xhr = _createAjax();
attachUploadProgress(xhr, options);
let method = options.method || "PUT";
xhr.open(method, url, true);
if (options.headers) {
for (let key in options.headers) {
xhr.setRequestHeader(key, options.headers[key]);
}
}
xhr.onreadystatechange = function () {
if (xhr.readyState != 4) {
return;
}
if (xhr.status == 200) {
resolve(xhr.response);
} else {
reject(xhr);
}
};
xhr.send(fileObj);
});
}
function iOSUpload(url, originalOptions, fileObj, resolve, reject) {
// log
var uri = url;
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileObj.name;
var headers = originalOptions.headers || {
"Content-Type": "application/octet-stream",
};
options.headers = headers;
let method = options.method || "PUT";
options.httpMethod = method;
const targetDirectory = window.cordova.file.dataDirectory;
window.resolveLocalFileSystemURL(
targetDirectory,
(dirEntry) => {
console.log("文件系统访问成功,目录:", dirEntry.fullPath);
// 2. 在目标目录中创建或获取文件
dirEntry.getFile(
options.fileName,
{ create: true, exclusive: false },
(fileEntry) => {
console.log("文件创建成功:", fileEntry.fullPath);
// 3. 创建文件写入器
fileEntry.createWriter(
(fileWriter) => {
// 写入成功回调
fileWriter.onwriteend = () => {
console.log("文件保存成功");
// 获取完整的本地文件路径
const localPath = fileEntry.toURL();
console.log("文件保存路径:", localPath);
var ft = new FileTransfer();
ft.upload(localPath, uri, onSuccess, onError, options);
};
// 写入失败回调
fileWriter.onerror = (e) => {
const errorMsg = `文件写入失败: ${e.toString()}`;
console.error(errorMsg);
reject(new Error(errorMsg));
};
try {
// 4. 写入文件数据
fileWriter.write(fileObj);
} catch (writeError) {
const errorMsg = `写入文件时发生异常: ${writeError.message}`;
console.error(errorMsg);
reject(new Error(errorMsg));
}
},
(writerError) => {
const errorMsg = `创建文件写入器失败: ${writerError.toString()}`;
console.error(errorMsg);
reject(new Error(errorMsg));
}
);
},
(fileError) => {
const errorMsg = `获取文件失败: ${fileError.toString()}`;
console.error(errorMsg);
reject(new Error(errorMsg));
}
);
},
(dirError) => {
const errorMsg = `解析本地文件系统URL失败: ${dirError.toString()}`;
console.error(errorMsg);
reject(new Error(errorMsg));
}
);
function onSuccess(r) {
console.log("Code = " + r.responseCode);
console.log("Response = " + r.response);
console.log("Sent = " + r.bytesSent);
resolve(r);
}
function onError(error) {
console.log("An error has occurred: Code = " + error.code);
console.log("upload error source " + error.source);
console.log("upload error target " + error.target);
console.log(error);
reject(error);
}
}
function pathsJoin(...args) {
let paths = [];
let firstStartsWithSlash = false;
if (args.length > 0) {
firstStartsWithSlash = args[0].startsWith("/");
}
for (let el of args) {
let t = el;
if (el.endsWith("/")) {
t = el.substr(0, el.length - 1);
} else if (el.startsWith("/")) {
t = el.substr(1, el.length);
}
paths.push(t);
}
let _path = paths.join("/");
return firstStartsWithSlash ? `/${_path}` : _path;
}
export function rebuildUrlIfNecessary(url, options) {
if (!url) {
return url;
}
//兼容相对路径地址
if (!url.startsWith("http") && options.baseUrl) {
url = pathsJoin(options.baseUrl, url);
return url;
}
return url;
}
export function getQuery(name, url) {
let query;
if (url) {
query = url.split("?")[1];
} else {
query = window.location.search.substr(1);
}
let vars = query.split("&");
for (let i = 0; i < vars.length; i++) {
let pair = vars[i].split("=");
if (pair[0] == name) {
return decodeURIComponent(pair[1]);
}
}
return null;
}
export function isIOS() {
// 检测 User Agent 中是否包含 iOS 相关标识
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
// 检测 iPhone, iPad, iPod
return /iPad|iPhone|iPod/.test(userAgent) && !window.MSStream;
}
export function isCordova() {
// 检测是否存在 cordova 或 phonegap 全局对象
return !!(window.cordova || window.phonegap || window.PhoneGap);
}