php中关于普通表单多文件上传的处理方法


Posted in PHP onMarch 25, 2011

然而有些情况只需要传递几个文件,而且文件体积并不太大,这种情况下使用组件则有点牛刀杀鸡的感觉,通过html自带的<input type="file">表单就可以实现需要的功能,关键在于后台接收程序的处理。

php处理上传做的很方便,上传文件的信息通过服务器自动处理到$_FILES数组中,开发者只需要使用的内置处理函数简单操作就可以啦。ASP开发者则没有这么幸运,官方并没有提供直接的处理方法,需要开发者自己设计,这时就需要开发者了解IIS对enctype="multipart/form-data"表单的处理方式,IIS把enctype="multipart/form-data"表单提交的数据存储成二进制数据,以二进制格式返回给开发者,开发者则需要通过LenB、MidB的字节处理函数来分析获取的上传内容,客户端发送的具体表单数据格式,可以了解下HTTP RFC1867协议传输格式方面的知识。

下面是我处理多个文件上传的方法,包括php和asp两个版本。

php:WEBSITE_DIRROOT代表网站根目录:

<?php 
/* 
* class: 文件上传类 
* author: 51JS.COM-ZMM 
* date: 2011.1.20 
* email: 304924248@qq.com 
* blog: http://www.cnblogs.com/cnzmm/ 
*/ class Upload { 
public $up_ext=array(), $up_max=5210, $up_dir; 
private $up_name, $up_rename=true, $up_num=0, $up_files=array(), $up_ret=array(); 
function __construct($name, $ext=array(), $rename=true) { 
if (!empty($name)) { 
$this->up_name = $name; 
!empty($ext) && $this->up_ext = $ext; 
$this->up_rename = $rename; 
$this->up_dir = WEBSITE_DIRROOT. 
$GLOBALS['cfg_upload_path']; 
$this->InitUpload(); 
} else { 
exit('upload文件域名称为空,初始化失败!'); 
} 
} 
private function InitUpload() { 
if (is_array($_FILES[$this->up_name])) { 
$up_arr = count($_FILES[$this->up_name]); 
$up_all = count($_FILES[$this->up_name], 1); 
$up_cnt = ($up_all - $up_arr) / $up_arr; 
for ($i = 0; $i < $up_cnt; $i ++) { 
if ($_FILES[$this->up_name]['error'][$i] != 4) { 
$this->up_files[] = array( 
'tmp_name' => $_FILES[$this->up_name]['tmp_name'][$i], 
'name' => $_FILES[$this->up_name]['name'][$i], 
'type' => $_FILES[$this->up_name]['type'][$i], 
'size' => $_FILES[$this->up_name]['size'][$i], 
'error' => $_FILES[$this->up_name]['error'][$i] 
); 
} 
} 
$this->up_num = count($this->up_files); 
} else { 
if (isset($_FILES[$this->up_name])) { 
$this->up_files = array( 
'tmp_name' => $_FILES[$this->up_name]['tmp_name'], 
'name' => $_FILES[$this->up_name]['name'], 
'type' => $_FILES[$this->up_name]['type'], 
'size' => $_FILES[$this->up_name]['size'], 
'error' => $_FILES[$this->up_name]['error'] 
); 
$this->up_num = 1; 
} else { 
exit('没找找到需要upload的文件!'); 
} 
} 
$this->ChkUpload(); 
} 
private function ChkUpload() { 
if (empty($this->up_ext)) { 
$up_mime = array('image/wbmp', 'image/bmp', 'image/gif', 'image/pjpeg', 'image/x-png'); 
foreach ($this->up_files as $up_file) { 
$up_allw = false; 
foreach ($up_mime as $mime) { 
if ($up_file['type'] == $mime) { 
$up_allw = true; break; 
} 
} 
!$up_allw && exit('不允许上传'.$up_file['type'].'格式的文件!'); 
if ($up_file['size'] / 1024 > $this->up_max) { 
exit('不允许上传大于 '.$this->up_max.'K 的文件!'); 
} 
} 
} else { 
foreach ($this->up_files as $up_file) { 
$up_ext = end(explode('.', $up_file['name'])); 
$up_allw = false; 
foreach ($this->up_ext as $ext) { 
if ($up_ext == $ext) { 
$up_allw = true; break; 
} 
} 
!$up_allw && exit('不允许上传.'.$up_ext.'格式的文件!'); 
if ($up_file['size'] / 1024 > $this->up_max) { 
exit('不允许上传大于 '.$this->up_max.'K 的文件!'); 
} 
} 
} 
$this->Uploading(); 
} 
private function Uploading() { 
if (IO::DIRCreate($this->up_dir)) { 
if (chmod($this->up_dir, 0777)) { 
if (!empty($this->up_files)) { 
foreach ($this->up_files as $up_file) { 
if (is_uploaded_file($up_file['tmp_name'])) { 
$file_name = $up_file['name']; 
if ($this->up_rename) { 
$file_ext = end(explode('.', $file_name)); 
$file_rnd = substr(md5(uniqid()), mt_rand(0, 26), 6); 
$file_name = date('ymdHis').'_'.$file_rnd.'.'.$file_ext; 
} 
$file_name = $this->up_dir.'/'.$file_name; 
if (move_uploaded_file($up_file['tmp_name'], $file_name)) { 
$this->up_ret[] = str_replace(WEBSITE_DIRROOT, '', $file_name); 
} else { 
exit('文件上传失败!'); 
} 
} 
} 
} 
} else { 
exit('未开启写入权限!'); 
} 
} else { 
exit('上传目录创建失败!'); 
} 
} 
public function GetUpload() { 
return empty($this->up_ret) ? false : $this->up_ret; 
} 
function __destruct() {} 
} 
?>

asp:
<% 
Class MultiUpload REM PUBLIC-VARIANT 
Public Form, IsFinished 
Private bVbCrlf, bSeparate, fPassed, formData, fileType, fileSize, folderPath, _ 
fRename, fIMGOnly, itemCount, chunkSize, bTime, sErrors, sAuthor, sVersion 
Private itemStart(), itemLength(), dataStart(), dataLength(), itemName(), itemData(), extenArr(), httpArr() 
REM CLASS-INITIALIZE 
Private Sub Class_Initialize 
Call InitVariant 
Server.ScriptTimeOut = 1800 
Set Form = Server.CreateObject("Scripting.Dictionary") 
sAuthor = "51JS.COM-ZMM" 
sVersion = "MultiUpload Class 3.0" 
End Sub 
REM CLASS-ATTRIBUTES 
Public Property Let AllowType(byVal sType) 
Dim regEx 
Set regEx = New RegExp 
regEx.Pattern = "^(\w+\|)*\w+$" 
regEx.Global = False 
regEx.IgnoreCase = True 
If regEx.Test(sType) Then fileType = "|" & Ucase(sType) & "|" 
Set regEx = Nothing 
End Property 
Public Property Let MaxSize(byVal sSize) 
If IsNumeric(sSize) Then fileSize = CDbl(FormatNumber(CCur(sSize), 2)) 
End Property 
Public Property Let SaveFolder(byVal sFolder) 
folderPath = sFolder 
End Property 
Public Property Let CommonPassed(byVal bCheck) 
fPassed = bCheck 
End Property 
Public Property Let FileRenamed(byVal bRename) 
fRename = bRename 
End Property 
Public Property Let FileIsAllImg(byVal bOnly) 
fIMGOnly = bOnly 
End Property 
Public Property Get SaveFolder 
SaveFolder = folderPath 
End Property 
Public Property Get FileRenamed 
FileRenamed = fRename 
End Property 
Public Property Get FileIsAllImg 
FileIsAllImg = fIMGOnly 
End Property 
Public Property Get ErrMessage 
ErrMessage = sErrors 
End Property 
Public Property Get ClsAuthor 
ClsAuthor = sAuthor 
End Property 
Public Property Get ClsVersion 
ClsVersion = sVersion 
End Property 
REM CLASS-METHODS 
Private Function InitVariant 
IsFinished = False 
bVbCrlf = StrToByte(vbCrlf & vbCrlf) 
bSeparate = StrToByte(String(29, "-")) 
fPassed = False 
fileType = "*" 
fileSize = "*" 
fRename = True 
fIMGOnly = True 
itemCount = 0 
chunkSize = 1024 * 128 
bTime = Now 
sErrors = "" 
End Function 
Public Function GetUploadData 
Dim curRead : curRead = 0 
Dim dataLen : dataLen = Request.TotalBytes 
Dim appName : appName = "PROGRESS" & IPToNum(GetClientIPAddr) 
Dim streamTmp 
Set streamTmp = Server.CreateObject("ADODB.Stream") 
streamTmp.Type = 1 
streamTmp.Open 
Do While curRead < dataLen 
Dim partLen : partLen = chunkSize 
If partLen + curRead > dataLen Then partLen = dataLen - curRead 
streamTmp.Write Request.BinaryRead(partLen) 
curRead = curRead + partLen 
LetProgress appName, Array(curRead, dataLen, DateDiff("s", bTime, Now), folderPath) 
Loop 
streamTmp.Position = 0 
formData = streamTmp.Read(dataLen) 
streamTmp.Close 
Set streamTmp = Nothing 
Call ItemPosition 
End Function 
Private Function LetProgress(byVal sName, byVal vArr) 
Application.Value(sName) = Join(vArr, "|") 
End Function 
Private Function DelProgress 
Application.Contents.Remove("PROGRESS" & IPToNum(GetClientIPAddr)) 
End Function 
Private Function ItemPosition 
Dim iStart, iLength : iStart = 1 
Do Until InStrB(iStart, formData, bSeparate) = 0 
iStart = InStrB(iStart, formData, bSeparate) + LenB(bSeparate) + 14 
iLength = InStrB(iStart, formData, bSeparate) - iStart - 2 
If Abs(iStart + 2 - LenB(formData)) > 2 Then 
ReDim Preserve itemStart(itemCount) 
ReDim Preserve itemLength(itemCount) 
itemStart(itemCount) = iStart 
itemLength(itemCount) = iLength 
itemCount = itemCount + 1 
End If 
Loop 
Call FillItemValue 
End Function 
Private Function FillItemValue 
Dim dataPart, bInfor 
Dim iStart : iStart = 1 
Dim iCount : iCount = 0 
Dim iCheck : iCheck = StrToByte("filename") 
For i = 0 To itemCount - 1 
ReDim Preserve itemName(iCount) 
ReDim Preserve itemData(iCount) 
ReDim Preserve extenArr(iCount) 
ReDim Preserve httpArr(iCount) 
ReDim Preserve dataStart(iCount) 
ReDim Preserve dataLength(iCount) 
dataPart = MidB(formData, itemStart(i), itemLength(i)) 
iStart = InStrB(1, dataPart, ChrB(34)) + 1 
iLength = InStrB(iStart, dataPart, ChrB(34)) - iStart 
itemName(iCount) = GetItemName(MidB(dataPart, iStart, iLength)) 
iStart = InStrB(1, dataPart, bVBCrlf) + 4 
iLength = LenB(dataPart) - iStart + 1 
If InStrB(1, dataPart, iCheck) > 0 Then 
bInfor = MidB(dataPart, 1, iStart - 5) 
extenArr(iCount) = FileExtenName(bInfor) 
httpArr(iCount) = GetHttpContent(bInfor) 
If IsNothing(extenArr(iCount)) Then 
itemData(iCount) = "" 
dataStart(iCount) = "" 
dataLength(iCount) = "" 
Else 
If Mid(folderPath, Len(folderPath) - 1) = "/" Then 
If fRename Then 
itemData(iCount) = folderPath & GetRandomName(6) & extenArr(iCount) 
Else 
itemData(iCount) = folderPath & GetClientName(bInfor) & extenArr(iCount) 
End If 
Else 
If fRename Then 
itemData(iCount) = folderPath & "/" & GetRandomName(6) & extenArr(iCount) 
Else 
itemData(iCount) = folderPath & "/" & GetClientName(bInfor) & extenArr(iCount) 
End If 
End If 
dataStart(iCount) = itemStart(i) + iStart - 2 
dataLength(iCount) = iLength 
End If 
Else 
extenArr(iCount) = "" 
httpArr(iCount) = "" 
itemData(iCount) = ByteToStr(MidB(dataPart, iStart, iLength)) 
dataStart(iCount) = "" 
dataLength(iCount) = "" 
End If 
iCount = iCount + 1 
Next 
Call ItemToColl 
End Function 
Private Function GetItemName(byVal bName) 
GetItemName = ByteToStr(bName) 
End Function 
Private Function ItemToColl 
For i = 0 To itemCount - 1 
If Not Form.Exists(itemName(i)) Then 
Form.Add itemName(i), itemData(i) 
End If 
Next 
End Function 
Private Function FileExtenName(byVal bInfor) 
Dim pContent, regEx 
pContent = GetClientPath(bInfor) 
If IsNothing(pContent) Then 
FileExtenName = "" 
Else 
Set regEx = New RegExp 
regEx.Pattern = "^.+(\.[^\.]+)$" 
regEx.Global = False 
regEx.IgnoreCase = True 
FileExtenName = regEx.Replace(pContent, "$1") 
Set regEx = Nothing 
End If 
End Function 
Private Function GetHttpContent(byVal bInfor) 
Dim sInfor, regEx 
sInfor = ByteToStr(bInfor) 
Set regEx = New RegExp 
regEx.Pattern = "^[\S\s]+Content-Type:([\S\s]+)$" 
regEx.Global = False 
regEx.IgnoreCase = True 
GetHttpContent = Trim(regEx.Replace(sInfor, "$1")) 
Set regEx = Nothing 
End Function 
Private Function GetRandomName(byVal sLen) 
Dim regEx, sTemp, arrFields, n : n = 0 
Set regEx = New RegExp 
regEx.Pattern = "[^\d]+" 
regEx.Global = True 
regEx.IgnoreCase = True 
sTemp = regEx.Replace(Now, "") & "-" 
Set regEx = Nothing 
arrFields = Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", _ 
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", _ 
"k", "l", "m", "n", "o", "p", "q", "r", "s", "t", _ 
"u", "v", "w", "x", "y", "z", "A", "B", "C", "D", _ 
"E", "F", "G", "H", "I", "J", "K", "L", "M", "N", _ 
"O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", _ 
"Y", "Z") 
Randomize 
Do While n < sLen 
sTemp = sTemp & CStr(arrFields(61 * Rnd)) 
n = n + 1 
Loop 
GetRandomName = sTemp 
End Function 
Private Function GetClientName(byVal bInfor) 
Dim pContent, regEx 
pContent = GetClientPath(bInfor) 
If IsNothing(pContent) Then 
GetClientName = "" 
Else 
Set regEx = New RegExp 
regEx.Pattern = "^.*\\([^\.]*)[^\\]+$" 
regEx.Global = False 
regEx.IgnoreCase = True 
GetClientName = regEx.Replace(pContent, "$1") 
Set regEx = Nothing 
End If 
End Function 
Private Function GetClientPath(byVal bInfor) 
Dim sInfor, pStart, pLength, pContent 
sInfor = ByteToStr(bInfor) 
pStart = InStr(1, sInfor, "filename=" & Chr(34)) + 10 
pLength = InStr(pStart, sInfor, Chr(34)) - pStart 
pContent = Mid(sInfor, pStart, pLength) 
GetClientPath = pContent 
End Function 
Public Function SaveUploadFile 
Dim isValidate 
Dim filePath, oStreamGet, oStreamPut 
isValidate = fPassed And CheckFile 
If isValidate Then 
For i = 0 To itemCount - 1 
If Not IsNothing(dataStart(i)) And Not IsNothing(dataLength(i)) Then 
If dataLength(i) = 0 Then 
itemData(i) = "" 
Else 
filePath = Server.MapPath(itemData(i)) 
If CreateFolder("|", ParentFolder(filePath)) Then 
Set oStreamGet = Server.CreateObject("ADODB.Stream") 
oStreamGet.Type = 1 
oStreamGet.Mode = 3 
oStreamGet.Open 
oStreamGet.Write formData 
oStreamGet.Position = dataStart(i) 
Set oStreamPut = Server.CreateObject("ADODB.Stream") 
oStreamPut.Type = 1 
oStreamPut.Mode = 3 
oStreamPut.Open 
oStreamPut.Write oStreamGet.Read(dataLength(i)) 
oStreamPut.SaveToFile filePath, 2 
oStreamGet.Close 
Set oStreamGet = Nothing 
oStreamPut.Close 
Set oStreamPut = Nothing 
End If 
End If 
End If 
Next 
IsFinished = True 
Else 
IsFinished = False 
End If 
End Function 
Private Function CheckFile 
Dim oBoolean : oBoolean = True 
CheckFile = oBoolean And CheckType And CheckSize 
End Function 
Private Function CheckType 
Dim oBoolean : oBoolean = True 
If fileType = "*" Then 
oBoolean = oBoolean And True 
Else 
For i = 0 To itemCount - 1 
If Not IsNothing(extenArr(i)) Then 
If InStr(1, fileType, "|" & Ucase(Mid(extenArr(i), 2)) & "|") > 0 Then 
If fIMGOnly Then 
Dim sAllow : sAllow = "|GIF|PJPEG|X-PNG|BMP|" 
Dim aCheck : aCheck = Split(UCase(httpArr(i)), "/") 
Dim iCheck : iCheck = "|" & aCheck(Ubound(aCheck)) & "|" 
If InStr(1, sAllow, iCheck, 1) > 0 Then 
oBoolean = oBoolean And True 
Else 
sErrors = sErrors & "表单 [ " & itemName(i) & " ] 的文件格式错误!\n" & _ 
"支持的格式为:" & Replace(Mid(fileType, 2, Len(fileType) - 1), "|", " ") & "\n\n" 
oBoolean = oBoolean And False 
End If 
Else 
oBoolean = oBoolean And True 
End If 
Else 
sErrors = sErrors & "表单 [ " & itemName(i) & " ] 的文件格式错误!\n" & _ 
"支持的格式为:" & Replace(Mid(fileType, 2, Len(fileType) - 1), "|", " ") & "\n\n" 
oBoolean = oBoolean And False 
End If 
End If 
Next 
End If 
CheckType = oBoolean 
End Function 
Private Function CheckSize 
Dim oBoolean : oBoolean = True 
If fileSize = "*" Then 
oBoolean = oBoolean And True 
Else 
For i = 0 To itemCount - 1 
If Not IsNothing(dataLength(i)) Then 
Dim tmpSize : tmpSize = CDbl(FormatNumber(CCur(dataLength(i)) / 1024, 2)) 
If tmpSize <= fileSize Then 
oBoolean = oBoolean And True 
Else 
sErrors = sErrors & "表单 [ " & itemName(i) & " ] 的文件大小 (" & tmpSize & " KB) 超出范围!\n" & _ 
"支持大小范围:<= " & fileSize & " KB\n\n" 
oBoolean = oBoolean And False 
End If 
End If 
Next 
End If 
CheckSize = oBoolean 
End Function 
Private Function CreateFolder(byVal sLine, byVal sPath) 
Dim oFso 
Set oFso = Server.CreateObject("Scripting.FileSystemObject") 
If Not oFso.FolderExists(sPath) Then 
Dim regEx 
Set regEx = New RegExp 
regEx.Pattern = "^(.*)\\([^\\]*)$" 
regEx.Global = False 
regEx.IgnoreCase = True 
sLine = sLine & regEx.Replace(sPath, "$2") & "|" 
sPath = regEx.Replace(sPath, "$1") 
If CreateFolder(sLine, sPath) Then CreateFolder = True 
Set regEx = Nothing 
Else 
If sLine = "|" Then 
CreateFolder = True 
Else 
Dim sTemp : sTemp = Mid(sLine, 2, Len(sLine) - 2) 
If InStrRev(sTemp, "|") = 0 Then 
sLine = "|" 
sPath = sPath & "\" & sTemp 
Else 
Dim Folder : Folder = Mid(sTemp, InStrRev(sTemp, "|") + 1) 
sLine = "|" & Mid(sTemp, 1, InStrRev(sTemp, "|") - 1) & "|" 
sPath = sPath & "\" & Folder 
End If 
oFso.CreateFolder sPath 
If CreateFolder(sLine, sPath) Then CreateFolder = True 
End if 
End If 
Set oFso = Nothing 
End Function 
Private Function ParentFolder(byVal sPath) 
Dim regEx 
Set regEx = New RegExp 
regEx.Pattern = "^(.*)\\[^\\]*$" 
regEx.Global = True 
regEx.IgnoreCase = True 
ParentFolder = regEx.Replace(sPath, "$1") 
Set regEx = Nothing 
End Function 
Private Function IsNothing(byVal sVar) 
IsNothing = CBool(sVar = Empty) 
End Function 
Private Function StrPadLeft(byVal sText, byVal sLen, byVal sChar) 
Dim sTemp : sTemp = sText 
Do While Len(sTemp) < sLen : sTemp = sChar & sTemp : Loop 
StrPadLeft = sTemp 
End Function 
Private Function StrToByte(byVal sText) 
For i = 1 To Len(sText) 
StrToByte = StrToByte & ChrB(Asc(Mid(sText, i, 1))) 
Next 
End Function 
Private Function ByteToStr(byVal sByte) 
Dim oStream 
Set oStream = Server.CreateObject("ADODB.Stream") 
oStream.Type = 2 
oStream.Mode = 3 
oStream.Open 
oStream.WriteText sByte 
oStream.Position = 0 
oStream.CharSet = "gb2312" 
oStream.Position = 2 
ByteToStr = oStream.ReadText 
oStream.Close 
Set oStream = Nothing 
End Function 
Private Function GetClientIPAddr 
If IsNothing(GetServerVar("HTTP_X_FORWARDED_FOR")) Then 
GetClientIPAddr = GetServerVar("REMOTE_ADDR") 
Else 
GetClientIPAddr = GetServerVar("HTTP_X_FORWARDED_FOR") 
End If 
End Function 
Private Function GetServerVar(byVal sText) 
GetServerVar = Request.ServerVariables(sText) 
End Function 
Private Function IPToNum(byVal sIp) 
Dim sIp_1, sIp_2, sIp_3, sIp_4 
If IsNumeric(Left(sIp, 2)) Then 
sIp_1 = Left(sIp, InStr(sIp, ".") - 1) 
sIp = Mid(sIp, InStr(sIp, ".") + 1) 
sIp_2 = Left(sIp, InStr(sIp, ".") - 1) 
sIp = Mid(sIp, InStr(sIp, ".") + 1) 
sIp_3 = Left(sIp, InStr(sIp, ".") - 1) 
sIp_4 = Mid(sIp, InStr(sIp, ".") + 1) 
End If 
IPToNum = CInt(sIp_1) * 256 * 256 * 256 + CInt(sIp_2) * 256 * 256 + CInt(sIp_3) * 256 + CInt(sIp_4) - 1 
End Function 
REM CLASS-TERMINATE 
Private Sub Class_Terminate 
Call DelProgress 
Form.RemoveAll 
Set Form = Nothing 
End Sub 
End Class 
%>

PHP 相关文章推荐
递归列出所有文件和目录
Oct 09 PHP
PHP 伪静态隐藏传递参数名的四种方法
Feb 22 PHP
利用Ffmpeg获得flv视频缩略图和视频时间的代码
Sep 15 PHP
php+mysql查询优化简单实例
Jan 13 PHP
CI(Codeigniter)的Setting增强配置类实例
Jan 06 PHP
PHP计算当前坐标3公里内4个角落的最大最小经纬度实例
Feb 26 PHP
CodeIgniter框架基本增删改查操作示例
Mar 23 PHP
[原创]PHP获取数组表示的路径方法分析【数组转字符串】
Sep 01 PHP
PHP实现websocket通信的方法示例
Aug 28 PHP
php 读取文件夹下所有图片、文件的实例
Oct 17 PHP
php workerman定时任务的实现代码
Dec 23 PHP
基于PHP实现短信验证码发送次数限制
Jul 11 PHP
PHP删除特定数组内容并且重建数组索引的方法.
Mar 25 #PHP
PHP学习 变量使用总结
Mar 24 #PHP
优化php效率,提高php性能的一些方法
Mar 24 #PHP
php 代码优化之经典示例
Mar 24 #PHP
php模拟asp中的XmlHttpRequest实现http请求的代码
Mar 24 #PHP
php邮件发送,php发送邮件的类
Mar 24 #PHP
php 数组排序 array_multisort与uasort的区别
Mar 24 #PHP
You might like
PHP5下$_SERVER变量不再受magic_quotes_gpc保护的弥补方法
2012/10/31 PHP
php输入数据统一类实例
2015/02/23 PHP
PHP实现的XML操作类【XML Library】
2016/12/29 PHP
javascript判断是手机还是电脑访问网页的简单实例分享
2014/06/03 Javascript
Javascript 完美运动框架(逐行分析代码,让你轻松了运动的原理)
2015/01/23 Javascript
JS实现状态栏跑马灯文字效果代码
2015/10/24 Javascript
jQuery基于BootStrap样式实现无限极地区联动
2016/08/26 Javascript
BootStrap Table 设置height表头与内容无法对齐的问题
2016/12/28 Javascript
Javascript中click与blur事件的顺序详析
2017/04/25 Javascript
nodejs6下使用koa2框架实例
2017/05/18 NodeJs
浅谈vue路径优化之resolve
2017/10/13 Javascript
jQuery EasyUI 折叠面板accordion的使用实例(分享)
2017/12/25 jQuery
浅谈在不使用ssr的情况下解决Vue单页面SEO问题(2)
2018/11/08 Javascript
微信小程序webview组件交互,内联h5页面并网页实现微信支付实现解析
2019/08/16 Javascript
NProgress显示顶部进度条效果及使用详解
2019/09/21 Javascript
微信小程序接入腾讯云验证码的方法步骤
2020/01/07 Javascript
[49:08]完美世界DOTA2联赛PWL S2 LBZS vs FTD.C 第一场 11.27
2020/12/01 DOTA
python中数据爬虫requests库使用方法详解
2018/02/11 Python
python socket网络编程之粘包问题详解
2018/04/28 Python
Python增强赋值和共享引用注意事项小结
2019/05/28 Python
django 使用全局搜索功能的实例详解
2019/07/18 Python
解决Django Static内容不能加载显示的问题
2019/07/28 Python
一行Python代码过滤标点符号等特殊字符
2019/08/12 Python
使用PyQt5实现图片查看器的示例代码
2020/04/21 Python
CSS3改变浏览器滚动条样式
2019/01/04 HTML / CSS
荷兰和比利时时尚鞋店:Van Dalen
2018/04/23 全球购物
德国的大型美妆个护电商:Flaconi
2020/06/26 全球购物
动物学专业毕业生求职信
2013/10/11 职场文书
运动会邀请函范文
2014/01/31 职场文书
校园文化建设方案
2014/02/03 职场文书
完整版商业计划书
2014/09/15 职场文书
实习生矿工检讨书
2014/10/13 职场文书
听证通知书
2015/04/24 职场文书
大学生心理健康活动总结
2015/05/08 职场文书
如何写新闻稿
2015/07/18 职场文书
小学语文的各类谚语(70首)
2019/08/15 职场文书