AJAX(二):axios 和 fetch函数发送AJAX请求、同源策略、 jsonp、CORS

一、各种发送AJAX请求

1.axios发送AJAX请求(重点)

安装axios: 脚手架目录npm i axios
先配置服务端,类型改成all,然后允许接收自定义请求头啥的

// (8)axios.html
app.all('/axios-server', (request, response) => {
    //设置响应头
    response.setHeader('Access-Control-Allow-Origin', '*');// 设置允许跨域
    response.setHeader('Access-Control-Allow-Headers', '*');//接收自定义请求头
    //响应一个数据
    const data = { name: 'ht' };
    let str = JSON.stringify(data); //对对象进行字符串转换
    //设置响应体
    response.send(str);
})

axios发送请求成功的值是一个封装好的响应对象:

在这里插入图片描述
我们想要的响应数据其实藏在response.data

来三个按钮:

<button>GET</button>
<button>POST</button>
<button>AJAX</button>
const get = document.querySelectorAll('button')[0];
const post = document.querySelectorAll('button')[1];
const ajax = document.querySelectorAll('button')[2];

(1)GET请求

get.onclick = function() {
    //GET请求
    axios.get('http://127.0.0.1:8000/axios-server',{
        //url参数
        params: {a:1,b:2},
        //请求头信息
        headers: {name:'zzy',age:18},
        //......
    }).then((response) => {
        //请求成功的回调
        console.log('全部响应结果:',response);
        console.log('响应状态码:', response.status);
        console.log('响应状态字符串:',response.statusText);
        console.log('响应头信息:', response.headers);
        console.log('响应体:', response.data);
    })
}

(2)POST请求

第二个参数对象里写请求体,第三个参数对象里写url参数和其他信息

   post.addEventListener('click', function() {
        //POST请求
        axios.post('http://127.0.0.1:8000/axios-server',{
            //第二个参数对象里写请求体
            username: 'zzy',
            password: '123'
        },{
            //url参数
            params: {a:1,b:2},
            //请求头信息
            headers: {name:'zzy',age:18}
        })
    })

(3)axios函数发送通用请求

    ajax.onclick = function() {
    // 通用请求
    axios({
        //请求方法
        method: 'POST',
        //url
        url: 'http://127.0.0.1:8000/axios-server',
        //url参数,传的是query类型参数,只是名字叫params
        params: {a:1,b:2},
        //请求头信息
        headers: {name:'zzy',age:18},
        //请求体参数
        data :{
            username: 'zzy',
            password: '123'
        },
        //超时时间2秒
        timeout:2000
    }).then((response) =>{
        console.log('全部响应结果:',response);
        console.log('响应状态码:', response.status);
        console.log('响应状态字符串:',response.statusText);
        console.log('响应头信息:', response.headers);
        console.log('响应体:', response.data);
    })
}

2.fetch发送AJAX请求

fetch比较牛逼的地方在于,它不想jquery和axios需要引入第三方库,它直接就能用,它就在window的内置对象中,直接就能用调用fetch函数。
fetch当然也有缺点,那就是返回的数据需要包两层promise,还有就是IE不兼容fetch

服务端随便搞一个

app.all('/fetch-server', (request, response) => {
    //设置响应头
    response.setHeader('Access-Control-Allow-Origin', '*');// 设置允许跨域
    response.setHeader('Access-Control-Allow-Headers', '*');//接收自定义请求头
    //响应一个数据
    const data = { name: 'ht' };
    let str = JSON.stringify(data); //对对象进行字符串转换
    //设置响应体
    response.send(str);
})

这里参数在url那传,和axios不太一样,然后响应体拿到的的json字符串,需要转换一下。这里不太熟悉,回头好好看看promise

btn.onclick = function() {
    fetch('http://127.0.0.1:8000/fetch-server?a=1&b=2',{
        //请求方法
        method: 'POST',
        //请求头
        headers: {name: 'zzy'},
        //请求体
        body: {
            username: 'zzy',
            password: '123'
        }
    }).then((response) => {
        return response.json();  //把json字符串转换为js对象
    }).then(response => { //第二个then处理上一个返回的正确结果
        console.log(response);
    });
}

3.JQuery发送AJAX请求

//GET请求
    $('button').eq(0).click(function () {
        $.get('http://127.0.0.1:8000/jquery-server',{
            a:100,b:1000
        },function (data) {//响应体
            console.log(data);
        },'json')//返回JSON类型
    })
    //POST请求
    $('button').eq(1).click(function () {
        $.post('http://127.0.0.1:8000/jquery-server',{
            a:100,b:1000
        },function (data) {//响应体
            console.log(data);
        })
    })
    //通用型方法ajax
    $('button').eq(2).click(function () {
        $.ajax({
           //请求类型
           type:'GET',
           //url
           url: 'http://127.0.0.1:8000/jquery-server',
            //参数
            data:{a:100,b:200},
            //响应体结果设置
            dataType:'json',
            //成功的回调
            success:function (data) {
                console.log(data);
            },
            //超时时间
            timeout:2000,
            //失败的回调
            error:function () {
                console.log('出错了!');
            },
            //头信息设置
            headers:{
               name:"lw",
                password:"lww"
            }
        });
    })

二、同源策略

同源策略就是协议、域名、端口号必须完全相同,有一个不一样就是跨域
这个地方听的比较懵,简单记录一下吧
搞个9000端口,从home传入index.html页面

const express = require('express');

const app = express();

app.get('/home', (request, response) => {
    //从home进来后,响应一个页面,这个页面里搞的东西都是同样的来源?
    response.sendFile(__dirname + '/index.html'); //拼接的是路径,不要加点
})

app.get('/data', (request, response) => {
    response.send('用户数据');
})

app.listen(9000, () => {
    console.log('服务已经启动,9000端口监听中...奥里给');
})

在index.html中,因为是在home下的,所以直接向/data发送请求是可以拿到响应体的

btn.onclick = function() {
    const xhr = new XMLHttpRequest();
    //这里因为满足同源策略,所以url可以简写
    xhr.open('GET', '/data');
    xhr.send();
    xhr.onreadystatechange = function() {
        if(xhr.readyState === 4) {
            if(xhr.status >= 200 && xhr.status < 300) {
                console.log(xhr.response);
            }
        }
    }
}

三、jsonp

理解不到位,暂时理解成响应体传过去原生js代码,可以解决跨域问题(通过script的src属性请求数据),但只能解决GET。而且这个也要和后端去配合,后端的响应体应该写成js代码才行,所以解决跨域问题用jsonp不多。更多情况是用脚手架的配置代理

1.原生jsonp

还是先搞个服务端,响应体传过去一个函数的调用

// (10)jsonp.html 检测用户名是否存在
app.all('/jsonp-server', (request, response) => {
    //响应一个数据
    const data = { exist: 1, msg: '用户名已存在' };
    let str = JSON.stringify(data); //对对象进行字符串转换
    //设置响应体
    response.send(`handle(${str})`);
})

实现用户名校验(模拟一下请求js代码的过程,并不是真的校验),服务端的响应体是一个函数的调用,那么我们就应该有这个函数,所以首先要声明handle函数,然后创建script标签,利用其src属性请求数据。

用户名:<input type="text" id="username">
<p></p>
<script>
    const input = document.querySelector('input');
    const p = document.querySelector('p');

    //声明handle函数
    function handle(data) {
        input.style.border = '1px solid #f00'; 
        p.innerHTML = data.msg;
        p.style.color = 'red';
    }

    input.addEventListener('blur', function() {
        let username = this.value;
        //向服务器发送请求,监测用户名是否存在
        //1.创建script标签
        const script = document.createElement('script');
        //2.设置标签的src属性
        script.src = 'http://127.0.0.1:8000/jsonp-server';
        //将script插入到文档中
        document.body.appendChild(script);
    })
</script>

2.JQuery发送jsonp请求

这块儿根本没懂是在干啥
服务端:

// (11)JQuery-jsonp.html 
app.all('/jquery-jsonp-server', (request, response) => {
    //响应一个数据
    const data = { name: 'zzy', age: 18 };
    let str = JSON.stringify(data); //对对象进行字符串转换

    //接收callback参数
    let callback = request.query.callback;
    //返回结果,这个callback就相当于是个函数名,相当于handle
    response.send(`${callback}(${str})`);
})
<button>点击发送jsonp请求</button>
<div id="result"></div>

<script>
    $('button').eq(0).click(function() { 
        //使用jquery发送jsonp请求时url后面要加参数callback=?,这是一个固定写法
        //Jquery中的getJSON,省去了jsonp中handle函数的定义,靠callback代替
        //这个callback参数传过去,好像可以变成一个函数,奇怪
        $.getJSON('http://127.0.0.1:8000/jquery-jsonp-server?callback=?',function(data){
            $('#result').html(`
                名称:${data.name}<br>
                年龄:${data.age}
            `)
        })
    })
</script>

四、CORS

跨域资源共享,全部都是服务端设置的东西

	//设置响应头  设置允许跨域
    response.setHeader("Access-Control-Allow-Origin","*");
    //任意头部信息
    response.setHeader("Access-Control-Allow-Headers","*");
    //预请求结果缓存
    response.setHeader("Access-Control-Max-Age","delta-seconds");
    //跨域请求时是否携带验证信息
    response.setHeader("Access-Control-Allow-Credentials","true");
    //设置请求允许的方法
    response.setHeader("Access-Control-Allow-Methods","*");
    //暴露头部信息
    response.setHeader("Access-Control-Expose-Headers","*");
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Axios可以通过使用JSONP来解决跨域问题。JSONP是JSON with Padding的缩写,是一种解决跨域请求的方法。JSONP通过在请求URL中传递一个回调函数名称,服务器端将数据包装在该回调函数的调用中返回给客户端,客户端再通过该函数接收并处理数据,这样就实现了跨域请求Axios中可以通过设置`jsonp: 'callback'`来开启JSONP跨域请求,其中`callback`是回调函数的名称。例如: ``` axios({ method: 'get', url: 'http://example.com/data', params: { id: 123 }, jsonp: 'callback' }) .then(response => { console.log(response.data) }) .catch(error => { console.log(error) }) ``` 在请求中设置了`params`参数,表示将该参数传递到服务器端,服务器端可以通过该参数返回相应的数据。同时,通过设置`jsonp: 'callback'`来开启JSONP请求,并指定回调函数的名称为`callback`。 在服务器端,需要将数据包装在回调函数的调用中返回给客户端。以Node.js为例,代码如下: ``` var express = require('express'); var app = express(); app.get('/data', function (req, res) { var id = req.query.id; var data = { id: id, name: 'John' }; var callback = req.query.callback; res.send(callback + '(' + JSON.stringify(data) + ')'); }); app.listen(3000, function () { console.log('Example app listening on port 3000!'); }); ``` 在上面的代码中,首先获取了客户端传递过来的`id`参数,然后构造数据`data`,最后获取客户端传递过来的回调函数名称`callback`,将数据包装在该回调函数的调用中返回给客户端。 通过上述方式,就可以使用AxiosJSONP功能来解决跨域请求了。 ### 回答2: Axios是一个非常流行的JavaScript库,它专门用于发送HTTP请求。然而,由于同源策略的限制,我们在使用Axios发送请求时,很容易碰到浏览器的跨域请求限制。在这种情况下,我们可以考虑使用Axios Jsonp来解决跨域问题。 JSONP(JSON Padding)是一种解决跨域问题的方式,它是通过不同的网址来加载一个JavaScript文件,该文件载入后会执行我们在网址中传入的回调函数,并且将我们需要的JSON数据作为参数传递给回调函数。通常情况下,我们可以通过动态创建一个<script>元素来实现JSONP请求。 在使用Axios Jsonp解决跨域问题时,我们需要先引入Jsonp插件,在Vue项目中,我们可以通过npm来安装: ``` npm i vue-jsonp --save-dev ``` 安装完成后,我们需要在main.js中将Jsonp插件引入: ``` import Vue from 'vue' import Jsonp from 'vue-jsonp' Vue.use(Jsonp) ``` 接下来,在需要发送Jsonp请求的地方,我们可以使用Axiosjsonp方法来实现: ``` this.$jsonp(url, { param: 'callback' }).then((response) => { console.log(response.data) }).catch((error) => { console.log(error) }) ``` 在这个例子中,我们使用了this.$jsonp方法来发送请求,并且指定了callback参数,这个参数在后台接受到请求后用来充当回调函数的名称。使用Axios Jsonp可以很方便地解决跨域问题,但是由于Jsonp本身的局限性,它也存在一些缺点。比如Jsonp只支持GET请求,无法使用POST等其他请求方法。同时,也存在安全性问题,因为Jsonp并不是一个真正的Ajax请求,所以无法像Ajax那样对请求进行全面的验证。如果需要更加严格的安全控制,我们需要考虑使用CORS(Cross-Origin Resource Sharing)或者代理来解决跨域问题。 ### 回答3: Axios 是一款流行的 HTTP 客户端库,它支持浏览器和 node.js 平台。它提供了很多接口来执行各种 HTTP 请求,例如 GET、POST、PUT、DELETE 等。但在浏览器中,由于跨域策略的限制,发送跨域请求会受到限制。浏览器限制的跨域请求包括 XMLHttpRequest、FetchAjax 等。 解决这个问题的一种方法是使用 JSONP,它是浏览器的一种跨域解决方案,允许在客户端从不同的域名请求数据。JSONP 的原理是通过动态创建 script 标签,将请求的数据封装在一个函数调用中,服务器返回的数据会被该函数接收并解析。在客户端通过 script 标签加载服务器返回的 js 文件,客户端收到 js 文件后直接执行其中的代码。因为返回的是一段 JavaScript 代码,所以不存在跨域问题。 Axios 提供了一个可以发送 JSONP 请求的接口,这个接口是 JSONP 接口的 promise 化版本。Axiosjsonp接口主要有两个参数,一个是url,另一个则是用于配置jsonp的一些选项和回调函数。 下面是 axios jsonp 的使用示例: ``` axios.jsonp('http://server.com/api', { params: { // 设置请求参数 name: 'apple', count: 10 }, jsonpCallback: 'callback', // 回调函数名字 timeout: 5000 // 超时时间 }) .then(function(response){ console.log(response); }) .catch(function(error){ console.log(error); }); ``` 在传递的配置选项中,`jsonpCallback` 是必选的选项,它指定了回调函数函数名。服务器返回的数据应该该函数名作为函数调用,并将请求的数据作为参数传入。在完成请求的时候,Axios 会调用这个函数来解析返回的数据。 Axios 通过动态创建 script 标签的方式发送 JSONP 请求,解决了同源策略限制下的跨域问题。同时,AxiosJSONP 的支持也使得开发者能够更加方便地获取数据,轻松构建跨域 Web 应用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值