Ajax的GET与POST和Ajax文件上传进度条

准备

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。 AJAX 不是新的编程语言,而是一种使用现有标准的新方法。 AJAX 是与服务器交换数据并更新部分网页的艺术,在不重新加载整个页面的情况下。

这里以我之前用PHP写的一个关于音乐上传与在线播放的小型页面作为基础,来理解和学习关于Ajax的基础知识;
当初写下的代码如下:

music.html

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>Cloud music</title>
</head>
<body>
<div id="from1">
    <p>Cloud music</p>
    <p>歌曲 : <input id="music_name" type="text" name="name" onkeypress="enterPress(event)"/>
        <input id="start" type="button" value="查询">
    </p>
</div>
<p id="music_playbox">欢迎使用云音乐服务!</p>
<p><a id="upload_link" href="upload_music.html">我有新的歌曲,我要上传到服务器!</a></p>
<script src="js/functions.js"></script>
</body>
</html>

music.php

<?php
$username='root';
$userpass='q12we3';
$host='127.0.0.1';
$database='music';
$conn=new mysqli($host,$username,$userpass,$database);
if(!$conn){
    echo 'Could not connect to database.';
    exit;
}

$name = trim($_GET['name']);
echo "<p>".$name."</p>";
$sql="SELECT * FROM `music` WHERE `address` LIKE '".'%'.$name.'%'."' ";
$result=$conn -> query($sql);
$row = $result -> fetch_row();
?>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Clude music</title>
</head>
<body>
    <?php 
    if($row[0]==""){
        echo "抱歉,歌曲库里并没有您搜索的歌曲呢..."."</br>"."您可以选择<a href='upload_music.html'>上传</a>...";
    }else{
        $test = $row[1].'-'.$row[0];
        $links = $row[2];
        echo "<p>"."播放 : ".$test."</p>";
        echo "<audio controls><source src='".$links."' type='audio/mp3' /></audio>";
    }
    ?>
</body>
</html>

upload_music.html

<!DOCTYPE html>
<html>
<head>
    <title>Upload - Cloud music</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
<form id="uploadForm" action="upload_music.php" method="POST" enctype="multipart/form-data">
    <p>填写歌曲详细信息 </p>
    <p>歌曲 : <input type="text" name="name" required/></p>
    <p>作家 : <input type="text" name="autor" required/></p>
    <p>上传文件 : <input type="file" name="userfile" required accept="audio/mpeg"/></p>
    <p><input id="submit" type="submit" value="上传"/></p>
</form>
</body>
</html>

upload_music.php

<?php
header("Content-Type:text/html;charset=utf-8");
$username='root';//数据库链接过程
$userpass='q12we3';
$host='127.0.0.1';
$database='music';
$conn=new mysqli($host,$username,$userpass,$database);
if(!$conn){
    echo 'Could not connect to database.';
    exit;
}
function formatBytes($size) {//存储数据单位转换
    $units = array(' B', ' KB', ' MB', ' GB', ' TB');
    for ($i = 0; $size >= 1024 && $i < 4; $i++)
    $size /= 1024;
    return round($size, 2).$units[$i];
    }
?>

<html>
<head>
    <title>Upload - Clude music</title>
</head>
<body>
<?php

if($_FILES['userfile']['error'] > 0) {//判断传入文件错误类型
    echo '上传失败 : ';
    switch ($_FILES['userfile']['error']) {
        case '1': echo '<p>抱歉,您上传的文件过大</p>';  
            break;
        case '2': echo '<p>抱歉,您上传的文件过大</p>';  
            break;
        case '3': echo '<p>抱歉,网络原因文件上传错误,请后退重新上传</p>';  
            break;
        case '4': echo '<p>抱歉,请正确选择文件</p>';  
            break;
        case '6': echo '<p>抱歉,系统错误,请联系管理员</p>';  
            break;
        case '7': echo '<p>抱歉,系统错误,请联系管理员</p>';  
            break;
    }
    exit;
}

$name = trim($_POST['name']);//html表单post到的信息
$autor = trim($_POST['autor']);
$fileurl = $_FILES['userfile']['tmp_name'];//上传后的临时文件地址
$filename = $_FILES['userfile']['name'];//用户文件名
$filesize = formatBytes($_FILES['userfile']['size']);//调用单位转换函数,将B转换为MB

/* 使用mime_content_type()函数进行文件MIME类型的判断
  比单纯的$_FILES['userfile']['type'];判断更加精确
  以防止文件过滤误伤 */
if(mime_content_type($fileurl) != "audio/mpeg") {
    echo "<p style='color:red;'>您上传的文件貌似不是mp3格式的文件呢~</p>";
    echo "您上传的文件类型为: ".mime_content_type($fileurl)."<p>请上传正确的MP3格式的文件~!</p>";
    exit;
}

$newname = $autor.'-'.$name.'.mp3';//创建新的文件名
$swichtype = "music/".iconv('utf-8','gbk',$newname);//将UTF-8编码转化为windows系统的GBK编码进行命名
move_uploaded_file($fileurl,$swichtype);//移动文件到置顶目录

echo "您正在上传 : ".$filename."<p> 大小 : ".$filesize."</p>".$newname."</p> ";

$address = "music/".$autor.'-'.$name.'.mp3';//创建以导入数据库的文件路径
$sql = "INSERT INTO `music` (`name`, `autor`, `address`) VALUES ('".$name."', '".$autor."', '".$address."');";

$result = $conn -> query($sql);
    if($result) {
        echo "<p style='color:green;'>恭喜,歌曲已经成功上传到云端~</p>";
    }else {
        echo "<p style='color:red;'>抱歉,您上传的歌曲在云端已经有了呢~,您可以尝试重新搜索~</p>";
    }
$conn -> close();
?>
</body>
</html>

以上就是我们初步搭建的一个基于php/mysql的小型B/S音乐站点,下面的Ajax实现过程均是基于此站点.

初始化Ajax

这里写图片描述

下面是一段Ajax的初始化实例:

var xmlhttp;
  if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
  }else{// code for IE6, IE5
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }

在IE7以下的浏览器中需要使用ActiveXObject来初始化,以上的版本就可以直接使用new XMLHttpRequest;

Ajax GET方法

一个简单的get

var txt = "兄弟";
xmlhttp.open("GET","music.php?name="+txt,true);
xmlhttp.send();

在music.php中,php程序get到name=”兄弟”的值对;返回相应的结果;
为了把结果显示在当前页面中,我们新建一个div,并使用onreadystatechange方法,返回结果

<div id="myDiv">
</div>
xmlhttp.onreadystatechange=function()
  {
    if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
      document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
    }
  }

if语句的意思是,当结果返回并准备好(readState的值为4)以及正确返回结果(status的值为200)时,将返回的文档显示在div中
尝试一下效果:

这里写图片描述

Ajax POST方法

如果需要像 HTML 表单那样 POST 数据,请使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定您希望发送的数据:

xmlhttp.open("POST","upload_music.php",true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");

如果需要将页面中表单的数据进行序列化,则可以使用new FormDate(form);

但是这个函数是h5的标准,对于那些不支持h5标准的浏览,这里提供一个函数seriaLize(form):

function seriaLize(form) {
    var parts = [],
        field = null,
        i,
        len,
        j,
        optLen,
        option,
        optValue;

    for (i = 0, len = form.elements.length; i < len; i++) {
        field = form.elements[i];

        switch (field.type) {
            case "select-one":
            case "select-multiple":
                if (field.name.length) {
                    for (j = 0, optLen = field.options.length; j < optLen; j++) {
                        option = field.options[j];
                        if (option.selected) {
                            optValue = "";
                            if (option.hasAttribute) {
                                optValue = (option.hasAttribute("value") ? option.value : option.text);
                            } else {
                                optValue = (option.attributes["value"].specified ? option.value : option.text);
                            }
                            parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(optValue));
                        }
                    }
                }
                break;
            case undefined:     //fieldset
            case "file":        //file input
            case "submit":      //submit button
            case "reset":       //reset button
            case "button":      //custom button
                break;

            case "radio":       //radio button
            case "checkbox":    //checkbox
                if (!field.checked) {
                    break;
                }
            /* falls through */

            default:
                //don't include form fields without names
                if (field.name.length) {
                    parts.push(encodeURIComponent(field.name) + "=" + encodeURIComponent(field.value));
                }
        }
    }
    return parts.join("&");
}

使用POST上传歌曲:

这里写图片描述

document.getElementById("submit").onclick = handleButtonPress;
    function handleButtonPress(event) {
        event.preventDefault(); //取消按钮的表单提交默认事件
        var form=document.getElementById("uploadForm");
        var formData = new FormData(form);

        var xmlhttp;
        if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
        } else {// code for IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }

        xmlhttp.onreadystatechange = function () {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
            }
        };
        xmlhttp.open("POST", form.action, true);
        xmlhttp.send(formData);
    }

好的 ,上传成功~!

这里写图片描述

添加进度条跟踪文件上传进度

Ajax中有一个进度事件progress,这个事件会在浏览器接收新数据期间周期性的触发.而onprogress事件处理程序会接收到一个event对象,其target属性是XHR对象,但包含着几个额外的属性比如:total,loaded,这样我们就能轻易的为用户创建一个进度指示器.

首先,我们给网页中添加一个进度条和一个显示百分比的span:

<progress id="prog" value="0"></progress>
<span id="progress"> 0%</span>

我们再来把刚才的js添加上我们需要的功能

    /**
     * Ajax上传数据进度条
     * @type {handleButtonPress}
     */
    document.getElementById("submit").onclick = handleButtonPress;
    function handleButtonPress(event) {
        event.preventDefault();
        var form=document.getElementById("uploadForm");
        var progress = document.getElementById("prog");
        var value = document.getElementById("progress");
        var formData = new FormData(form);

        var xmlhttp;
        if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
        } else {// code for IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }

        var upload = xmlhttp.upload;
        upload.onprogress = function(e){
            progress.max = e.total;
            progress.value = e.loaded;
            //计算当前百分比
            var sum = Math.round((progress.value/progress.max)*100);
            value.innerHTML = sum+"%";
        };
        upload.onload = function(e){
            progress.value = 1;
            progress.max = 1;
        };

        xmlhttp.onreadystatechange = function () {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                document.getElementById("myDiv").innerHTML = xmlhttp.responseText;
            }
        };
        xmlhttp.open("POST", form.action, true);
        xmlhttp.send(formData);
    }

好了,尝试着上传一个大一点的东西试试:

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

效果还不错!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值