AJAX(二) axios、fetch发送请求,同源策略,跨域解决方案等

目录

(一)其他函数的AJAX请求发送

1.axios函数

(1)发送get请求

(2)发送post请求

(3)axios函数发送请求

2.fetch函数(较少使用)

(二)跨域

1.同源策略

(1)概念

(2)案例证明

2.解决跨域的方案

(1)JSONP

(2)CORS


(一)其他函数的AJAX请求发送

1.axios函数

引入axios方法:

  1. 在<head>里引入<script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.6/axios.js"></script>(bootstrap网站里找)
  2. 下载axios:npm install axios -g

推荐第一种方法

服务端:

app.all('/axios-server', (request, response) => {
    // 设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*')
    // 设置响应头 允许任意类型的请求头
    response.setHeader('Access-Control-Allow-Headers', '*')
    // 设置发送
    response.send('response from axios!')
})

(1)发送get请求

// 点击get发送请求
btns[0].addEventListener('click', function () {
    // get请求
    axios.get('/axios-server', {
    // url参数
    params: {
        id: 123,
        vip: true
    },
    // 请求头信息
    headers: {
        Name: 'csq',
        Age: 18
    }
}).then(response => (
        console.log(response) //获取响应结果 promise的then函数
    ))
})

promise的then()函数,现在还不清楚具体的功能和原理,学完ajax就补

用于获取响应体的信息

 

(2)发送post请求

// 点击post发送请求 
btns[1].addEventListener('click', function () {
    // 发送post 格式:post(url{},{请求体data},{其他参数})
    axios.post('/axios-server', {
        // 请求体
        uname: 'admin',
        pwd: '123'
    }, {
        // 其它参数
        // url参数
        params: {
            id: 1,
            vip: true
        },
        // 请求头
        headers: {
            Name: 'csq',
            Age: 18
        }    
    })
})

 格式:post(url{},{请求体data},{其他参数}) 

(3)axios函数发送请求

// 点击ajax 用axios函数发送请求
btns[2].addEventListener('click', function () {
    axios({
        // 发送方式(默认get)
        method: 'POST',
        // url
        url: '/axios-server',
        // url参数
        params: {
            id: 1,
            vip: true
        },
        // 请求头
        headers: {
            Name: 'csq',
            Age: 18
        },
        // 请求体
        data: {
            uname: 'admin',
            pwd: '123'
        }
    }).then(response => {
        // promise 获取数据
        console.log(response)
        console.log(response.status)
        console.log(response.statusText)
        console.log(response.headers)
        console.log(response.data)
        console.log(response.config.headers.Name)
    })
})

 

2.fetch函数(较少使用)

服务端:

// fetch函数 响应路由规则
app.all('/fetch-server', (request, response) => {
    // 设置响应头 设置允许跨域
    response.setHeader('Access-Control-Allow-Origin', '*')
    // 设置响应头 允许任意类型的请求头
    response.setHeader('Access-Control-Allow-Headers', '*')
    // 设置发送
    response.send('response from fetch!')
})
// fetch函数发送请求
btn.addEventListener('click', function () 
    fetch('http://127.0.0.1:8000/fetch-server', {
        // 发送方式
        method: 'POST',
        // url参数
        params: { 
            id: 123,
            vip: true
        },
        // 请求头信息
        headers: {
            Name: 'csq',
            Age: 18
        }, 
        // 请求体 字符串类型 还有别的类型:formData等
        body: 'uname=admin&pwd=123'
        // 响应体的结果获取 then返回promise类型
    }).then(response => {
        return response.text()//转换成字符串类型
        // return response.json() //转换成json类型
    }).then(response => {
        console.log(response)
    })
})

 此处使用两个then()函数 

(二)跨域

1.同源策略

(1)概念

同源策略是浏览器最核心最基本的安全功能

如果2个URL的协议、域名(主机)、端口号都相同,则称它们同源

同源策略是浏览器的行为,是为了保护本地数据不被JavaScript代码获取回来的数据污染

如果非同源(即跨域),那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问,因此拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收

跨域不能进行如下操作:

  • Cookie、LocalStorage 和 IndexDB 无法读写
  • DOM 和 Js对象无法获得
  • AJAX请求不能发送

可以跨域的标签:

在浏览器中, <script> 、<img>、<iframe>、<link>等标签都可以跨域加载,而不受浏览器的同源策略的限制, 这些带src属性的标签每次加载的时候,实际上都是浏览器发起一次GET请求, 不同于普通请求(XMLHTTPRequest)的是,通过src属性加载的资源,浏览器限制了JavaScript的权限,使其不能读写src加载返回的内容

(2)案例证明

服务端:

// 1.引入express
const express = require('express')
// 2.创建初始对象
const app = express()
// 3.路由机制 get
app.get('/server', (request, response) => {
    // 发送文件 __dirname:绝对路径 D:\ajax\跨域\1.同源策略
    response.sendFile(__dirname + '/index.html')
})

// /data
app.get('/data', (request, response) => {
    response.send('数据来了数据来了')
})

// 4.端口监听事件
app.listen(8000, () => {
    console.log('服务器8000端口正在运行中...')
})

        发送文件:sendFile(__dirname+'文件名') 

index.html文件 :

    <!-- 引入axios -->
    <script crossorigin="anonymous" src="https://cdn.bootcdn.net/ajax/libs/axios/1.3.6/axios.js"></script>
</head>

<body>
    <h1>同源策略</h1>
    <button>点击发送请求</button>
    <script>
        // 点击按钮发送请求
        const btn = document.querySelector('button')
        // 用axios函数发送ajax
        btn.addEventListener('click', function () {
            // 因为同源,故url路径可省略简写为/data即可
            axios.get('/data', {}).then(response => {
                console.log(response.data)
            })
        })
    </script>
</body>

index.html和服务端server.js同源,点击按钮发送请求正确

 若将index.html以liveServer形式打开,因为liveServer用的是5500端口,则与服务端不同源

 报错,不能发送ajax请求(maybe)

2.解决跨域的方案

(1)JSONP

原理:动态创建script标签,src属性指向没有跨域限制;指向一个接口,接口返回的格式一定是函数表达式(数据)

jsonp的使用:

1、动态创建script标签

        const script = document.createElement('script')

2、添加script路径

        script.src = 'server.js的路径'

3、将script标签插入到目标位置

        document.body.appendChild(script

jsonp的缺点

1、只支持get请求,不支持post等请求

2、多次点击后页面会存在大量废弃script标签,使用onload事件在script标签作用后立即删除

案例分析

输入用户名,若已经存在则输入框边框变为红色,提示用户名已存在

<body>
    <input type="text">
    <p></p>
    <script>
        // 判断输入的内容在服务端内是否存在,不存在则输入框变为红色边框,文字提示重复
        const ipt = document.querySelector('input')
        const p = document.querySelector('p')
        // 失去焦点事件 用change/blur
        ipt.addEventListener('change', function () {
            // 动态创建script标签
            const script = document.createElement('script')
            // 写src
            script.src = 'http://127.0.0.1:8000/check-uname'
            // 将标签写到p标签后
            document.body.appendChild(script)
        })

        // 声明handle函数
        function handle(data) {
            // 如果值相等表明重复
            if (data.uname === ipt.value) {
                p.innerHTML = data.msg
                p.style.color = 'red'
                ipt.style.border = '2px solid red'
            } else {
                p.innerHTML = ''
                ipt.style.border = '1px solid #000'
            }
        }
    </script>
</body>

服务端:

// 1.引入express
const express = require('express')
// 2.创建初始对象
const app = express()
// 3.路由机制 get
app.get('/check-uname', (request, response) => {
    const data = {
        uname: 'csq',
        age: 18,
        msg: '输入用户名已存在!'
    }
    // 将对象转换为字符串
    let str = JSON.stringify(data)
    // 调用handle函数
    response.send(`handle(${str})`)
})

// 4.端口监听事件
app.listen(8000, () => {
    console.log('服务器8000端口正在运行中...')
})

 弊端:

多次进行get请求后页面会留存大量script标签,造成大量冗余

 解决方法:用onload事件,即用即删,script标签完全加载完毕后触发

// 失去焦点事件 用change/blur
ipt.addEventListener('change', function () {
    // 1.动态创建script标签
    const script = document.createElement('script')
    // 2.写src
    script.src = 'http://127.0.0.1:8000/check-uname'
    // 3.将标签写到p标签后
    document.body.appendChild(script)

    // 多次请求get事件后,页面留存大量script标签
    // 4.用onload事件,即用即删
    script.addEventListener('load', function () {
        script.remove()
    }) 
})

此时script标签已删除 

(2)CORS

跨域资源共享是一种基于 HTTP 头的机制,该机制通过允许服务器标示除了它自己以外的其他(域、协议或端口),使得浏览器允许这些源访问加载自己的资源

CORS工作原理:

通过设置一个响应头来告诉浏览器该请求允许跨域,浏览器接收到该响应后就会响应对方 

允许跨域的响应头

response.setHeader('Access-Control-Allow-Origin','*') 

更多响应头见下方链接

跨源资源共享(CORS) - HTTP | MDN

(三)小感悟

终于算是肤浅的学完了ajax?还有很多细节不熟悉,等以后遇到了具体的再补吧,学前端进度还不到30%...继续加油!!! 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值