Ajax的学习整理

来源博客:【Harryの心阁


Ajax运行原理

Ajax相当于浏览器发送请求与接受响应的代理人,以实现不影响用户浏览页面的情况下,局部更新页面数据,从而提高用户体验

实现步骤

  1. 创建Ajax对象 new XMLHttpRequest()
  2. 告诉Ajax请求地址以及请求方式 open
  3. 发送请求send方法
  4. 获取服务器端给予客户端的响应数据 onload 获取响应数据responseText
// 1. 创建ajax对象
var xhr = new XMLHttpRequest()
// 2. 告诉ajax对象发送的位置,和方式,第一个参数是请求方式,第二个请求地址
xhr.open('get', 'http://localhost:3000/first')
// 3. 发送请求
xhr.send()
// 4. 获取响应数据
xhr.onload = function(){
console.log(xhr.responseText);
}

响应的数据格式

  1. json对象作为响应数据的格式,请求返回的数据为json字符串
  2. 将json字符串转化为json对象
// 1. 创建ajax对象
var xhr = new XMLHttpRequest()
// 2. 告诉ajax对象发送的位置,和方式,第一个参数是请求方式,第二个请求地址
xhr.open('get', 'http://localhost:3000/responseData')
// 3. 发送请求
xhr.send()
// 4. 获取响应数据,接受完请求后onload事件自动响应
xhr.onload = function(){
// 返回的是字符串类型
// console.log(xhr.responseText);
// 将json字符串转换为json对象
let respnseText = JSON.parse(xhr.responseText)
console.log(respnseText);
console.log(typeof respnseText);
// 将转换的json对象中的信息获取,并且将数据信息渲染到页面中
let str = `<h2>${respnseText.name}</h2>`
document.body.innerHTML = str
}

请求参数传递

  1. get请求xx.open('get',url)
        let username =document.querySelector('#username')
        let email =document.querySelector('#email')
        let submit =document.querySelector('#submit')

        // 给按钮添加一个点击事件
        submit.onclick = function(){
            // 获取从用户在表单中输入的值
            let emaildata = email.value
            let usernamedata = username.value
            // 对获取到数据进行字符串的拼接
            let str = `username=${usernamedata}&email=${emaildata}`
            // 创建一个ajax对象
            console.log(str);
            let xhr = new XMLHttpRequest()
            // 创建ajax对象的请求方式
            xhr.open('get',`http://localhost:3000/get?${str}`)
            xhr.send()
            xhr.onload = function(){
                console.log(xhr.responseText);
            }
        }
// res.send(req.query)
  1. get请求只能的请求头类型只能是application/x-www-form-urlencoded,并且在解析请求地址时通过 body-parser中的urlencoded()方法进行解析,get请求不能提交对象数据格式的

post请求方式

  1. 请求的方式为json时,如果要得到请求的json内容 需要使用 body-parser中的bodyPaser.json()方法
    // 1. 创建ajax对象
    var xhr = new XMLHttpRequest()
    // 2. 告诉ajax对象发送的位置,和方式,第一个参数是请求方式,第二个请求地址
    xhr.open('post', 'http://localhost:3000/json')
    xhr.setRequestHeader('Content-Type','application/json');
    
    // 3. 发送请求
    xhr.send(JSON.stringify({name:'list',age:50}))
    // 4. 获取响应数据,接受完请求后onload事件自动响应
    xhr.onload = function(){
        // 返回的是字符串类型
        console.log(xhr.responseText);
        // 将json字符串转换为json对象
    }

ajax状态码

  1. 获取服务器端的响应
  2. 0 请求未初始化
  3. 1 请求以及简历,但是还没有发送
  4. 2 请求已经发送
  5. 3 表示请求正在处理中,部分代码可以使用
  6. 4 响应已经完成
  7. xhr.readyState 获取Ajax状态码 onreadystatechange事件
  8. onload比以上事件的请求方式更为效率

ajax错误处理

  1. xhr.status获取http状态码 400
  var btn = document.getElementById('btn')
        // 当用户点击后发送错误请求
        btn.onclick=()=>{
            var xhr = new XMLHttpRequest()
            xhr.open('get','http://localhost:3000/error')
            // 对请求的http的状态码进行判断
            xhr.send();
            xhr.onload=()=>{
                console.log(xhr.status);
                if(xhr.status === 400){
                    alert(xhr.responseText)
                }
            }
        }
  1. 404错误状态码 输入错误的情况较多 ,检测请求地址是否有误
  2. 500错误代码时服务器端错误
  3. 断网时无法触发onload事件,可以执行onerror()事件

注意ajax状态码表示的是服务器的请求过程的状态,http状态码表示的是请求的结果

低版本的缓存问题

  1. 在请求地址上加一个参数,并且保证每次请求参数的值不同即可

同步异步

  1. 封装一个简单的异步函数get
  2. get请求需要拼接到请求地址的后方,post请求放在send的方法中
function ajax (params){
    let xhr = new XMLHttpRequest();
    let options = ''
    params.data.forEach((v,i)=>{
        params += v + '=' + params.data[i] + '&'
    })
    params.substr(0,params.length-1)
    xhr.open(
        params.type,params.url
    )
    xhr.send()
    xhr.onload = ()=>{
        params.success(xhr.responseText)
    }
}
ajax({
    type:'get',
    url:'http://localhost:3000/first1',
    data:{
        name:'zs',
        age:20
    }
    success:(data)=>{
        console.log('这里是success函数'+data);
    }
})
  1. 封装get请求和post请求参数的时候
function ajax(params) {
    let xhr = new XMLHttpRequest();
    let options = ''
    for (let attr in params.data) {
        options += attr + '=' + params.data[attr] + '&'
    }
    options = options.substr(0, options.length - 1)
    // console.log(options)
    if (params.type === 'get') {
        params.url = params.url + '?' + options
    }
    xhr.open(params.type, params.url)
    if (params.type == 'post') {
        let contentType = params.header['Content-Type']
        xhr.setRequestHeader('Content-Type', contentType)
        if (contentType === 'application/json') {
            xhr.send(JSON.stringify(params.data))
        } else {
            xhr.send(options)
        }
    } else {
        xhr.send()
    }
    xhr.onload = () => {
        // 对http的状态码进行判断如果状态码为200则调用success函数,如果失败则调用error函数
        if (xhr.status == 200) {
            let responseHeader = xhr.getResponseHeader('Content-Type')
            let resText = xhr.responseText
            if (responseHeader.includes('application/json')) {
                resText = JSON.parse(resText)
            }
            params.success(resText, xhr)
        } else {
            params.error(resText, xhr)
        }
    }
}
ajax({
    type: 'get',
    url: 'http://localhost:3000/responseData',
    data: {
        name: 'sz',
        age: 20
    },
    header: {
        'Content-Type': 'application/json'
        // 'Content-Type':'application/x-www-form-urlencoded'
    },
    success: (data,xhr) => {
        console.log('这里是success函数');
        console.log(data);
        console.log(xhr);
    },
    error: (data) => {
        console.log('这里是error函数' + data);
    }
})
  1. 获取请求中的数据 getResponseHeader()方法 在页面加载完成后调用onload事件中 如果获取到的请求类型为application/json类型,将json字符串以json对象的方式输出,使用方法JSON.parse()
  2. Object.assign() 如果目标对象和源对象有同名属性,或者多个源对象有同名属性,则后面的属性会覆盖前面的属性。如果该函数只有一个参数,当参数为对象时,直接返回该对象;当参数不是对象时,会先将参数转为对象然后返回。并且该方法是浅拷贝
function ajax(params) {
    // 给ajax设定一个默认值
    let defaults = {
        type: 'get',
        url: '',
        data: {},
        header: {
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        success: (data) => {

        },
        error: (data) => {

        }
    }
    // 使用Object.assign()方法 将之间的对象覆盖
    Object.assign(defaults,params)
    let xhr = new XMLHttpRequest();
    let options = ''
    for (let attr in params.data) {
        options += attr + '=' + defaults.data[attr] + '&'
    }
    options = options.substr(0, defaults.length - 1)
    // console.log(options)
    if (defaults.type === 'get') {
        defaults.url = defaults.url + '?' + options
    }
    xhr.open(defaults.type, defaults.url)
    if (defaults.type == 'post') {
        let contentType = defaults.header['Content-Type']
        xhr.setRequestHeader('Content-Type', contentType)
        if (contentType === 'application/json') {
            xhr.send(JSON.stringify(defaults.data))
        } else {
            xhr.send(options)
        }
    } else {
        xhr.send()
    }
    xhr.onload = () => {
        // 对http的状态码进行判断如果状态码为200则调用success函数,如果失败则调用error函数
        if (xhr.status == 200) {
            let responseHeader = xhr.getResponseHeader('Content-Type')
            let resText = xhr.responseText
            if (responseHeader.includes('application/json')) {
                resText = JSON.parse(resText)
            }
            defaults.success(resText, xhr)
        } else {
            defaults.error(resText, xhr)
        }
    }
}
ajax({
    url: 'http://localhost:3000/responseData',
    data: {
        name: 'sz',
        age: 20
    },
    success: (data, xhr) => {
        console.log('这里是success函数');
        console.log(data);
        console.log(xhr);
    }
})

模板引擎

  1. 使用模板引擎 art-template 在客户端的使用步骤
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>模板引擎</title>
    <script src="/js/art-template.js"></script>
</head>
<body>
    <div class="container"></div>
    <script type="text/html" id="idt">
        <h1>{{username}} {{age}}</h1>
    </script>
    <script type="text/javascript">
        let html = template('idt',{username:'zs',age:20})
        document.querySelector('.container').innerHTML = html
    </script>
</body>
</html>

验证邮箱

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>验证邮箱地址</title>
    <script src="/js/ajax.js"></script>
    <!-- <script src="/js/template.js"></script> -->
</head>

<body>
    <style>
        body {
            background: -webkit-linear-gradient(left, rgb(216, 236, 235), rgb(241, 229, 241));
        }

        .box {
            margin: 200px auto;
            display: flex;
            justify-content: center;
            align-items: center;
            flex-direction: column;
        }

        .email_login {
            border-radius: 10px;
            width: 400px;
            height: 30px;
            padding: 10px;
            /* outline-color: aliceblue; */
        }

        .email_login:hover {
            outline-color: bisque;
            border: none;
        }

        .message {
            background: rgb(221, 208, 208);
        }

        .success {
            background-color: rgb(82, 82, 173);
        }

        .error {
            background-color: rgb(226, 106, 106);
        }
    </style>
    <div class="box">
        <input type="email" class="email_login" value="" placeholder="请在此输入您要初测的邮箱账号!!">
        <p class="message"></p>
    </div>
    <script type="text/javascript">
        // 获取元素
        let email = document.querySelector('.email_login')
        let message = document.querySelector('p')
        // 当输入框失去焦点时的事件
        email.onblur = function () {
            // console.log(e);
            // 获取用户输入的值,对用户输入的值判断
            let email_value = this.value
            // 正则判断输入的值
            let reg = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
            if (!reg.test(email_value)) {
                message.innerHTML = '输入的邮箱规则格式有误,请重新输入!!!'
                message.className = 'message'
                return;
            }
            ajax({
                type: 'post',
                url: "http://localhost:3000/emailbox",
                data: {
                    email: email_value
                },
                success: function (response) {
                    if (response.message.includes('恭喜')) {
                        message.innerHTML = response.message
                        message.className = 'success'
                    } else {
                        message.innerHTML = response.message
                        message.className = 'error'
                    }
                },
                error: (res) => {
                    message.innerHTML = res.message
                    message.className = 'error'
                }
            });
        }

    </script>
</body>
</html>

{% folding green, 请求路由 %}

app.get('/emailbox',(req,res)=>{
    if(req.query.email == 'iui9@qq.com'){
        res.send({message:'您好邮箱已注册,请您重新输入!!'})
    }else{
        res.send({message:'恭喜您注册的邮箱可用!!!!'})
    }
})
app.post('/emailbox',(req,res)=>{
    if(req.body.email == 'iui9@qq.com'){
        res.send({message:'您好邮箱已注册,请您重新输入!!'})
    }else{
        res.send({message:'恭喜您注册的邮箱可用!!!!'})
    }
})

{% folding green, ajax封装 %}

function ajax(params) {
    // 给ajax设定一个默认值
    let defaults = {
        type: 'get',
        url: '',
        data: {},
        header: {
            'Content-Type': 'application/json'
        },
        success: (data) => {},
        error: (data) => {}
    }
    // 使用Object.assign()方法 将之间的对象覆盖
    Object.assign(defaults,params)
    let xhr = new XMLHttpRequest();
    let options = ''
    for (let attr in params.data) {
        options += attr + '=' + defaults.data[attr] + '&'
    }
    options = options.substr(0, defaults.length - 1)
    // console.log(options)
    if (defaults.type === 'get') {
        defaults.url = defaults.url + '?' + options
    }
    xhr.open(defaults.type, defaults.url)
    if (defaults.type == 'post') {
        let contentType = defaults.header['Content-Type']
        xhr.setRequestHeader('Content-Type', contentType)
        if (contentType === 'application/json') {
            xhr.send(JSON.stringify(defaults.data))
        } else {
            xhr.send(options)
        }
    } else {
        xhr.send()
    }
    xhr.onload = () => {
        // 对http的状态码进行判断如果状态码为200则调用success函数,如果失败则调用error函数
        if (xhr.status == 200) {
            let responseHeader = xhr.getResponseHeader('Content-Type')
            let resText = xhr.responseText
            if (responseHeader.includes('application/json')) {
                resText = JSON.parse(resText)
            }
            defaults.success(resText, xhr)
        } else {
            defaults.error(resText, xhr)
        }
    }
}

搜索框内容自动提示

  1. 使用定时器的操作,延时对请求接口发送ajax请求,在每次请求之前将之前的定时器清除
  2. 设置防抖操作,对用户输入的值进行判断如果用户没有在手术框中输入内容,将提示信息 使用trim()函数,将文本框中的空格清除 阻止程序向下执行 return

三级联动(省市区)

  1. 接口地址:接口地址
  2. JSON.stringify() 方法可以将对象的数据存储在本地的内存中
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>三级联动 省市区</title>
    <script src="js/ajax.js"></script>
    <script src="js/art-template.js"></script>
</head>
<style>
    body {
        background-color: #ccc;
    }

    .box {
        margin: 100px auto;
        width: 500px;
        height: 300px;
        display: flex;
        justify-content: center;
        align-items: center;
    }
</style>

<body>
    <div class="box">
        <div class="form_group">
            <select name="" id="province">
                <!-- <option value="">请选择省份</option> -->
            </select>
        </div>
        <div class="form_group">
            <select name="" id="city">
                <option value="">请选择城市</option>
            </select>
        </div>
        <div class="form_group">
            <select name="" id="area">
                <option value="">请选择县城</option>
            </select>
        </div>
    </div>
</body>
<script type="text/html" id="provinceTpl">
    <option value="">请选择省份</option>
    {{each provices_list}}
        <option value="{{$value.pindex}}">{{$value.provices_list}}</option>
    {{/each}}
</script>
<script type="text/html" id="cityTpl">
    <option value="">请选择城市</option>
    {{each city_lists}}
    <option value="">{{$value.citysName}}</option>
    {{/each}}
</script>
<script>
    // 封装一个函数
    let All_lists = []
    function getaddressData() {
        ajax({
            type: "get",
            url: "https://cdn.jsdelivr.net/gh/Rr210/image@master/hexo/4/province1.json",
            success: function (response) {
                console.log(response);
                All_lists = response.provinces
                localStorage.setItem('address_data', JSON.stringify(response.provinces))
            }
        });
    }
    let province = document.querySelector('#province')
    let city = document.querySelector('#city')
    let addressData = localStorage.getItem('address_data')
    if (!addressData) {
        this.getaddressData()
    } else {
        All_lists = JSON.parse(addressData)
        let provices_list = All_lists.map((v,i) => {
            let arr = {provices_list:v.provinceName,pindex:i}
            return arr
        })
        // console.log(provices_list);
        let html = template('provinceTpl',{provices_list})
        province.innerHTML = html
    }
    // 给省份选择框添加一个改变事件监听 select的变化
    province.onchange = function(e){
        let id = this.value
        let city_lists = JSON.parse(addressData)[Number(id)].citys
        // console.log(city_lists);
        let html1 = template('cityTpl',{city_lists})
        city.innerHTML = html1
    }
</script>

</html>

FormData对象的作用

  1. 模拟HTML表单
  2. 异步上传二进制文件
  3. 本身是一个构造函数
  4. 使用formidable模块来解析FormData对象
  5. formData.get(‘属性名’),formData.set(‘属性名’,‘属性值’),formData.delete(‘key’),formData.append(‘key’,‘value’)
  6. 默认接收最后一个实例方法
  7. set方法和append方法的区别:在属性名已经存在的情况下,set会覆盖原来的键名的值,append会保留两个值
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FormData对象</title>
</head>
<body>
    <form id="form">
        <input type="text" name="username" id="" />
        <input type="password" name="password" id="" />
        <input type="button" id="btn" value="提交"/>
    </form>
    <script type="text/javascript">
    // 获取按钮
    var btn = document.querySelector('#btn')
    var form = document.querySelector('#form')
    btn.onclick = function(){
        // 将普通的html表单转换为表单对象
        let formData = new FormData(form)
        let xhr = new XMLHttpRequest()
        xhr.open('post','http://localhost:3000/formData')
        // 发送ajax请求
        xhr.send(formData)
        // 监听xhr对象下面的onload事件
        xhr.onload = function(){
            if(xhr.status==200){
                console.log(xhr.responseText);
            }
        }
    }
    </script>
</body>
</html>
// 加入formidable模板
app.post('/formData',(req,res)=>{
    const form = new formidable.IncomingForm();
    form.parse(req,(err,fields,files)=>{
        res.send(fields)
    })
})

formData二进制上传

  1. get请求方式不能用于文件的上传
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FormData二进制文件的上传</title>
</head>

<body>
    <input type="file" name="" id="file" />
    <script type="text/javascript">
        let file = document.querySelector('#file')
        file.onchange = function(){
            let formData = new FormData()
            formData.append('attrName',this.files[0])
            var xhr = new XMLHttpRequest()
            xhr.open('post','http://localhost:3000/up_file')
            xhr.send(formData)
            xhr.onload = function(){
                if(xhr.status==200){
                    console.log(xhr.responseText);
                }
            }
        }
    </script>
</body>

</html>

上传进度条

  1. 使用上传事件中的onprogress事件
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>上传进度条</title>
</head>
<style>
    .progress_warp{
        width: 800px;
        height: 40px;
        background-color: #ccc;
        border-radius: 5px;
    }
    .progress_event{
        border-radius: 5px;
        width: 0;
        height: 100%;
        color: #fff;
        background-color: rgb(53, 27, 68);
    }
</style>
<body>
    <input type="file" name="" id="file" />
    <div class="progress_warp">
        <div class="progress_event" style="width: 0%;" id="bar"></div>
    </div>
    <script type="text/javascript">
        let file = document.querySelector('#file')
        let bar = document.querySelector('#bar')
        file.onchange = function(){
            let formData = new FormData()
            formData.append('attrName',this.files[0])
            var xhr = new XMLHttpRequest()
            xhr.open('post','http://localhost:3000/up_file')
            xhr.upload.onprogress = function(e){
                // console.log(e);
                let bar_data = (e.loaded / e.total).toFixed(2) * 100 + '%'
                bar.style.width = bar_data
                bar.innerHTML = bar_data
            }
            xhr.send(formData)
            xhr.onload = function(){
                if(xhr.status==200){
                    console.log(xhr.responseText);
                }
            }
        }
    </script>
</body>
</html>

图片加载预览

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>上传进度条</title>
</head>
<style>
    .progress_warp{
        width: 800px;
        height: 40px;
        background-color: #ccc;
        border-radius: 5px;
    }
    .box_img{
        padding: 20px;
    }
    .box_img img{
        width: 100px;
        border-radius: 10px;
    }
    .progress_event{
        border-radius: 5px;
        width: 0;
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 20px;
        font-weight: 550;
        margin: 10px 0;
        height: 100%;
        color: #fff;
        background-color: rgb(53, 27, 68);
    }
</style>
<body>
    <input type="file" name="" id="file" />
    <div class="box_img">
        
    </div>
    <div class="progress_warp">
        <div class="progress_event" style="width: 0%;" id="bar"></div>
    </div>
    <script type="text/javascript">
        let file = document.querySelector('#file')
        let bar = document.querySelector('#bar')
        let box_img = document.querySelector('.box_img')
        file.onchange = function(){
            let formData = new FormData()
            formData.append('attrName',this.files[0])
            var xhr = new XMLHttpRequest()
            xhr.open('post','http://localhost:3000/up_file')
            xhr.upload.onprogress = function(e){
                // console.log(e);
                let bar_data = (e.loaded / e.total).toFixed(2) * 100 + '%'
                bar.style.width = bar_data
                bar.innerHTML = bar_data
            }
            xhr.send(formData)
            xhr.onload = function(){
                if(xhr.status==200){
                    // console.log(xhr.responseText);
                    // 动态创建一个图片 将上传的文件的路径名称赋值给uploads
                    let img = document.createElement('img')
                    img.src= '/uploads' + JSON.parse(xhr.responseText).path
                    // 调用图片上传成功的事件onload
                    img.onload = function (){
                        box_img.appendChild(img)
                    }
                }
            }
        }
    </script>
</body>
</html>

ajax问题

  1. ajax不能向非同源服务器端发送请求
  2. 使用jsonp解决同源限制问题
  • 将不同源的服务器请求地址写在script标签的src属性中
  • 服务端响应数据必须是以一个函数的调用
  • 在客户端全局作用域下定义函数fn(在script标签的上面)
  • 在函数内部对服务器端返回的数据进处理

post请求格式

  1. 必须有请求头:content-type:application/x-www-form-unlencoded
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>post请求的两种方式</title>
</head>

<body>
    <!-- 第一种使用url形式的请求方式 -->
    <!-- <script type="text/javascript">
        let xhr = new XMLHttpRequest()
        xhr.open('post', 'http://localhost:3000/post')
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
        params = "name=zs&age=12"
        xhr.send(params)
        xhr.onload = function () {
            console.log(xhr.responseText);
        }
    </script> -->
    <!-- 第二种使用json形式 -->
    <script type="text/javascript">
        let xhr = new XMLHttpRequest()
        xhr.open('post', 'http://localhost:3000/post')
        xhr.setRequestHeader('Content-Type', 'application/json')
        params = {
            name: 'zs',
            age: 2
        }
        xhr.send(JSON.stringify(params))
        xhr.onload = function () {
            console.log(xhr.responseText);
        }
    </script>
</body>
</html>

jsonp请求封装

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>jsonp的调用</title>
</head>

<body>
    <button id="btn1">jsonP提交</button>
    <button id="btn2">jsonP提交</button>
    <script>
        let btn1 = document.getElementById('btn1')
        let btn2 = document.getElementById('btn2')
        btn2.onclick = function () {
            jsonP({
                url: 'http://localhost:3000/better',
                data:{
                    name:'zs',
                    age:23
                },
                success: (e) => {
                    console.log(e)
                    console.log(123)
                }
            })
        }
        // 封装一个jsonP函数
        function jsonP(e) {
            var script = document.createElement('script')
            // 将传递的data取出来
            params = ''
            for(let arr in e.data){
                params+=`&${arr}=${e.data[arr]}`
            }
            // 设置window下的随机函数名
            fName = 'myjson' + Math.random().toString().replace('.', '')
            // 设置src中的请求地址
            window[fName] = e.success
            script.src = e.url + `?callback=${fName+params}`
            document.body.appendChild(script)
            script.onload = function () {
                document.body.removeChild(script)
            }
        }
    </script>
</body>
</html>
app.get('/better',(req,res)=>{
    // const fName = req.query.callback
    // const result = fName + '({name:"zs"})'
    // res.send(result)
    res.jsonp({name:'zs',age:98})
})

腾讯天气API

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://cdn.jsdelivr.net/gh/Rr210/hexofixed@v0.47/js/jquery-3.5.1.min.js"></script>
    <link rel="stylesheet"
        href="https://cdn.jsdelivr.net/gh/Rr210/hexofixed@frame/frame/bootstrap/3/css/bootstrap.min.css">
    <script src="https://cdn.jsdelivr.net/gh/Rr210/hexofixed@frame/frame/bootstrap/3/js/bootstrap.min.js"></script>
    <script src="/js/art-template.js"></script>
    <title>Document</title>
</head>
<style>
    .ta{
        margin: 100px;
    }
    th{
        text-align: center;
    }
</style>
<body>
    <div class="ta table-responsive">
        <table class="table table-striped table-bordered table-hover text-center">
            <thead>
                <tr>
                    <th>degree</th>
                    <th>update_time</th>
                    <th>weather</th>
                    <th>weather_code</th>
                    <th>weather_short</th>
                    <th>wind_direction</th>
                    <th>wind_power</th>
                </tr>
            </thead>
            <tbody id='html'></tbody>
        </table>
    </div>
    <script src="/js/jsonp.js"></script>
    <script type="text/html" id="tpl">
        {{each info}}
        <tr>
            <td>{{$value.degree + '°'}}</td>
            <td class="">{{dateFormat($value.update_time)}}</td>
            <td>{{$value.weather}}</td>
            <td>{{$value.weather_code}}</td>
            <td>{{$value.weather_short}}</td>
            <td>{{$value.wind_direction}}</td>
            <td>{{$value.wind_power+'级'}}</td>
        </tr>
        {{/each}}
    </script>
    <script>
        let datas = document.getElementById('html')
        // 构造一个date函数
        function dateFormat(dates){
            let year = dates.substr(0,4)
            let mounth = dates.substr(4,2)
            let day = dates.substr(6,2)
            let hour = dates.substr(8,2)
            let min = dates.substr(10,2)
            return `${year}-${mounth}-${day} ${hour}:${min}`
        }
        // 将自定义函数开放到模板中
        template.defaults.imports.dateFormat = dateFormat
        jsonP({
            url: 'https://wis.qq.com/weather/common',
            data: {
                source: 'pc',
                weather_type: 'forecast_1h|forecast_24h',
                province: '山西省',
                city: '晋中市'
            },
            success: (e) => {
                // console.log(e);
                let html = template('tpl', { info: e.data.forecast_1h })
                // console.log(html);
                datas.innerHTML = html
            }
        })
    </script>
</body>

</html>

cors 跨域资源共享

  1. 使用express方法 设置请求的报文
  2. 使用express模块中的中间件拦截请求 app.use
  3. 设置服务器的响应报文 res.header('Access-Control-Allow-Origin','*')
  4. 设置请求方法 res.header('Access-Control-Allow-Method':'get,post')
  5. 注意在使用中间件拦截时 一定要注意放行,否则无法执行后面的内容 next()

}

app.use((req,res,next)=>{
    res.header('Access-Control-Allow-Origin','*')
    res.header('Access-Control-Allow-Methods','get,post')
    next()
})

cookie复习

  1. withCredentials:指定在涉及到跨域请求时,是否携带cookie信息,默认值为false
  2. Access-Control-Allow-Credentials:true 允许客户端发送请求时携带cookie
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>设置cook信息</title>
</head>

<body>
    <form id="loginForm">
        <input type="text" placeholder="用户名" name="username" />
        <input type="password" placeholder="密码" name="pwd" />
    </form>
    <button id="logined">登录</button>
    <button id="checklogin">检测登录</button>
    <script>
        let loginform = document.getElementById('loginForm')
        let logined = document.getElementById('logined')
        let checklogin = document.getElementById('checklogin')
        // 监听请求
        logined.onclick = function () {
            let formData = new FormData(loginform)
            let xhr = new XMLHttpRequest()
            xhr.open('post', 'http://localhost:3000/logins')
            xhr.withCredentials = true
            xhr.send(formData)
            xhr.onload = function () {
                console.log(xhr.responseText);
            }
        }
        checklogin.onclick = function(){
            let xhr = new XMLHttpRequest()
            xhr.open('get', 'http://localhost:3000/checklogin')
            // xhr.withCredentials = true
            xhr.send()
            xhr.onload = function () {
                console.log(xhr.responseText);
            }
        }
    </script>
</body>
</html>
app.post('/logins', (req, res) => {
    // console.log(res);
    const form = new formidable.IncomingForm();
    form.parse(req, (err, fields, files) => {
        console.log(fields);
        if (fields.username == '123' && fields.pwd == '123') {
            req.session.isLogin = true
            res.send({ message: '登录成功', code: 1 })
        } else {
            res.send({ message: '登录失败', code: -1 })
        }
        // res.send(fields)
    })
    // 解析formdata
})
app.get('/checklogin', (req, res) => {
    if (req.session.isLogin) {
        res.send({ message: '当前已登录' })
    }else{
        res.send({message:'当前未登录'})
    }
})

jquery中的$.ajax()

  1. 请求参数时,默认为application/x-www-form-encoded
  2. 如果使用json对象,需要将json对象转换成json字符串,并且将类型设置为application/json
  3. beforeSend 表示在发送ajax请求前执行的 可在其中测试传递的参数,不满足条件可以使用return false

seralize方法

  1. 将表单中的数据自动拼接成字符串类型,如:name=zs&age=12
  2. 使用sealizeArray()方法将用户输入的内容转换成数组形式
  3. 封装一个函数使数组形式转换为json对象
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>使用jquery中的serialize方法</title>
</head>

<body>
    <form id="form">
        <input type="text" name="username" placeholder="用户名" />
        <input type="password" name="pwd" placeholder="用户名" />
        <input type="submit" value="提交" />
    </form>
    <script src="https://cdn.jsdelivr.net/gh/Rr210/hexofixed@v0.47/js/jquery-3.5.1.min.js"></script>
    <script>
        $('#form').on('submit', function () {
            //    let params =  $("#form").serialize()
            //    console.log(params);
            //    return false;
            serializeObject($(this))
            return false
        })
        function serializeObject(obj) {
            let result = {}
            let params = obj.serializeArray()
            // console.log(params)
            $.each(params,(index,item)=>{
                result[item.name] = item.value
            })
            console.log(result);
            return result
        }
    </script>
</body>

</html>

$.ajax() 发送jsonp请求

  1. dataType:'jsonp'
  2. jsonCallback:'fnName' 指定函数名称
  3. jsonp:'cb' 修改callback名称
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>使用jquery中的jsonp方法</title>
    <script src="https://cdn.jsdelivr.net/gh/Rr210/hexofixed@v0.47/js/jquery-3.5.1.min.js"></script>
</head>
<body>
    <button id="btn">
        发送请求
    </button>
    <script>
        // $('#btn').on('click',function(){
        //     $.ajax({
        //         type:'get',
        //         url:'jsonp',
        //         success:(res)=>{
        //             console.log(res);
        //         }
        //     })
        // })
        $('#btn').on('click',function(){
            $.ajax({
                url:"/jsonp",
                type:'get',
                dataType:'jsonp',
                success:(res)=>{
                    console.log(res);
                }
            })
        })
    </script>
</body>
</html>
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Harry-iu

顺手给小编加个鸡腿????

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值