教程.AJAX

本文介绍了AJAX的核心概念和优点,展示了原生JavaScript、jQuery和Vue中使用AJAX进行异步数据交互的例子。同时,提到了NodeJS作为后端处理AJAX请求的示例,并讨论了AJAX与PHP的交互。文章还详细解释了XHR的readyState属性和跨域问题,以及解决方案,如设置CORS头。
摘要由CSDN通过智能技术生成

AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。

最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。




AJAX示例

在同目录,html文件中写入下面代码,并且该目录下创建文件 ”input.txt“。



JS 原生写法

思路:

  1. 创建xhr请求
  2. 监听xhr状态变化,若 请求已完成,且响应已就绪,则执行相应操作例如:在div中展示内容
  3. 打开请求,存入内容,并发送出去
<div id="div">点击下方按钮,修改该内容</div>
<button id="btn" onclick="loadXMLDoc()">按钮</button>

<script>
    function loadXMLDoc() {
        var xhr = new XMLHttpRequest();

        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                document.getElementById("div").innerHTML = xhr.responseText;
            }
        }

        xhr.open("get", "input.txt", true); // true,指使用异步。而false指同步。
        xhr.send();
    }
</script>


jQuery ajax

如下:

<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script>
    $.ajax({
        method: "get",
        url: "http://localhost:8080/query",
        data: {
            filename: "input.txt",
        },
        success: function (res) {
            console.log(res);
        },
        error: function (err) {
            console.log(err);
        },
    });
</script>


Vue axios

如下,

// https://cdn.staticfile.org/axios/0.18.0/axios.min.js

// 前端代码
axios({
    method: "get",
    url: "http://localhost:8080/query",
    params: {
        filename: "input.txt",
    }
}).then((res)=>{
    console.log(res.data);
});


// NodeJS 代码
const express = require('express');
const app = express();
const cors = require('cors');
app.use(cors());
const fs = require('fs');

app.get('/query', (req, res) => {
    console.log('查询的参数');
    console.log(req.query);
    var filename = req.query.filename;
    fs.readFile(filename, (err, data) => {
        if (err) {
            console.log(err);
            res.send(err);
        } else {
            res.send(data); // 如果成功,返回文件内容
        }
    });
})

// 端口必须要监听
app.listen(8080, () => {
    console.log("http://localhost:8080")
})


其他方法

jQuery load()

语法为: $(selector).load(URL,data,callback);

如下所示:

<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<div id="div1"></div>
<script>
    $("#div1").load("input.txt");
</script>

jQuery get()

语法为: $.get('URL',callback);

如下所示:

<script src="https://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script>
<script type="text/javascript">
    $.get("http://localhost:8080/query", { filename: "input.txt" }, (res) => console.log(res));
</script>



前后端交互

AJAX与PHP

html代码如下

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title></title>
    <script src="../../link/jquery.js"></script>
    <script src="../../link/vue@2.6.14.js"></script>
</head>

<body>
    <div id="app">
        <!-- 普通查询 -->
        <button style="margin-top: 40px;" @click="getData">查询</button>
        <div id="content1"></div>

        <!-- 带参数查询 -->
        <button style="margin-top: 40px;" @click="getData2(para)">查询传参数</button> <input v-model="para" type="text" />
        <div id="content2"></div>

        <!-- 选择器查询 -->
        <form style="margin-top: 40px;">
            <select name="users" v-model="this.para2" @change="getData3(this.para2)">
                <option value="">选择一个</option>
                <option value="1">1</option>
                <option value="2">2</option>
                <option value="3">3</option>
            </select>
        </form>
        <br>
        <div id="content3"></div>
    </div>



    <script>
        const app = new Vue({
            el: '#app',
            data() {
                return {
                    para: 1,
                    para2: ''
                }
            },
            methods: {
                getData() {
                    $.ajax({
                        url: "getData.php",
                        success: function (res) {
                            // 处理返回数据,为json对象
                            console.log(res);
                            res = JSON.parse("[" + res.replace(/}{/g, "},{") + "]");
                            console.log(res);

                            var data = [];
                            for (i in res) {
                                $("#content1").append(res[i].name + ",")
                            }
                        },
                        error: function (xhr) {
                            console.log(xhr);
                        }
                    })
                },

                getData2(para) {
                    $.ajax({
                        url: "getData.php?para=" + para,
                        success: function (res) {
                            console.log(res);
                            console.log(this.url);
                            $("#content2").html(res)
                        },
                        error: function (xhr) {
                            console.log(xhr);
                        }
                    })
                },

                getData3(str) {
                    $.ajax({
                        url: "getData.php?para=" + str,
                        success: function (res) {
                            console.log(str);
                            console.log(this.url);
                            console.log(res);
                            $('#content3').html(res)
                        },
                        error: function (xhr) {
                            console.log(xhr);
                        }
                    })
                }
            },
        })

    </script>

    <style>
    </style>

</body>

</html>

getData.php 代码如下,

<?php
$para = isset($_GET["para"]) ? intval($_GET["para"]) : '';

// 定义连接
$con = mysqli_connect('localhost', 'root', '123456');
if (!$con) {
    die('Could not connect: ');
}
// 定义数据库
mysqli_select_db($con, "test");
// 定义编码,防止中文乱码
mysqli_set_charset($con, "utf8");

// 定义SQL语句
$sql1 = "SELECT * FROM user";
$sql2 = "SELECT * FROM user WHERE id = '" . $para . "'";

// 判断是否存在参数,并执行相应的查询
if ($para) {
    $sql = $sql2;
} else {
    $sql = $sql1;
};

// 定义查询结果
$result = mysqli_query($con, $sql);

while ($row = mysqli_fetch_array($result)) {
    echo '{"id":"' .  $row['id'] . '","name":"' .  $row['name'] . '","age":"' .  $row['age'] . '"}';
};

mysqli_close($con);




XHR readystate

属性描述
onreadystatechange存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。
readyState存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。0: 请求未初始化 1: 服务器连接已建立 2: 请求已接收 3: 请求处理中 ``4: 请求已完成,且响应已就绪
status200: “OK”``404: 未找到页面



服务器响应

如需获得来自服务器的响应,请使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性。

属性描述
responseText获得字符串形式的响应数据。
responseXML获得 XML 形式的响应数据。



跨域问题

1. 什么是跨域

跨域是指跨域名的访问,以下情况都属于跨域:

跨域原因说明示例
域名不同www.jd.com 与 w ww.taobao.com
域名相同,端口不同ww.jd.com:8080www.jd.com:8081
二级域名不同item.jd.commiaosha.jd.com

如果域名和端口都相同,但是请求路径不同,不属于跨域,如:

www.jd.com/itemwww.jd.com/goods


2. 为什么存在跨域问题

跨域问题 是浏览器针对ajax的一种限制。一个页面发起的ajax请求,只能是于当前页同域名的路径,这能有效的阻止跨站攻击。


3. 解决方案

在后端,例如NodeJS代码中处理,如下两种方案。

直接使用setHeader

http.createServer(function (req, res) {})中插入代码如下:

res.setHeader("Access-Control-Allow-Origin", "*");
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
res.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.setHeader("X-Powered-By", ' 3.2.1')
res.setHeader("Content-Type", "application/json;charset=utf-8");

或者使用express框架

首先,需要定义app,通过express框架

var express = require('express')
const app = express()

解决跨域接收请求

//设置跨域请求
app.all('*', function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild');
    res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
    res.header("X-Powered-By", ' 3.2.1')
    res.header("Content-Type", "application/json;charset=utf-8");
    next();
});

解决跨域返回

// 使用中间件 允许跨域
// app.use(path,中间件函数)
app.use('/', (req, res, next) => {
    // 注意, 需要带 '*'
    res.set('Access-Control-Allow-Origin', '*');        
    next();
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值