AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)。
最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
AJAX示例
在同目录,html文件中写入下面代码,并且该目录下创建文件 ”input.txt“。
JS 原生写法
思路:
- 创建xhr请求
- 监听xhr状态变化,若 请求已完成,且响应已就绪,则执行相应操作例如:在div中展示内容
- 打开请求,存入内容,并发送出去
<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: 请求已完成,且响应已就绪 |
status | 200: “OK”``404: 未找到页面 |
服务器响应
如需获得来自服务器的响应,请使用 XMLHttpRequest 对象的 responseText 或 responseXML 属性。
属性 | 描述 |
---|---|
responseText | 获得字符串形式的响应数据。 |
responseXML | 获得 XML 形式的响应数据。 |
跨域问题
1. 什么是跨域
跨域是指跨域名的访问,以下情况都属于跨域:
跨域原因说明 | 示例 |
---|---|
域名不同 | www.jd.com 与 w ww.taobao.com |
域名相同,端口不同 | ww.jd.com:8080 与 www.jd.com:8081 |
二级域名不同 | item.jd.com 与 miaosha.jd.com |
如果域名和端口都相同,但是请求路径不同,不属于跨域,如:
www.jd.com/item
与 www.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();
});