Ajax&Fetch学习笔记 03、跨域问题

举报
长路 发表于 2022/11/28 21:36:57 2022/11/28
【摘要】 文章目录前言一、认识跨域1.1、介绍跨域(含示例)1.2、同域与不同域区别1.3、跨域请求为什么被阻止?二、两种解决方案方案1:CORS(IE10及以上选择)方案2:JSONP(IE10以下选择方案) 前言 本篇博客是跨域问题解决,若文章中出现相关问题,请指出! 所有博客文件目录索引:博客目录索引(持续更新) 一、认识跨域 1.1、介绍跨域(含示例) 跨域:向一个域发送请求,如果要请求的域和当前域

@[toc]

前言

本篇博客是跨域问题解决,若文章中出现相关问题,请指出!

所有博客文件目录索引:博客目录索引(持续更新)

一、认识跨域

1.1、介绍跨域(含示例)

跨域:向一个域发送请求,如果要请求的域和当前域是不同域即为跨域。不同域之间的骑牛,就是跨域请求。

示例

<script>
    //访问本地资源实际就是同域:http://localhost:5500/main.css
    // const url = "./main.css";  
    //下面这个请求就是不同域,若是我们在本地向改地址发送一个ajax请求,就会出现跨域问题!
    const url = "https://blog.csdn.net/cl939974883";
    const xhr = new XMLHttpRequest();

    xhr.onreadystatechange = () => {
        if (xhr.readyState != 4) return;

        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
            console.log(xhr.responseText);
        }
    }

    xhr.open("GET", url, true);

    xhr.send(null);
</script>

image-20210713211915457



1.2、同域与不同域区别

一般一个请求地址为:https://www.imooc.com:443/course/list

  • 组成:https(协议)://www.imooc.com(域名):443(端口号)/course/list(路径)
  • 协议、域名、端口号、路径。

不同域指的是协议域名端口号只要其中一个不一样就是不同域!!!对于只是路径不一样的话是同域。

image-20210713213549035



1.3、跨域请求为什么被阻止?

原因:阻止跨域请求,其实是浏览器本身的一种安全策略—同源策略!!!实际上本质后端也是响应过来的,只是浏览器在接收解析响应时会对响应的内容就是检查,若是不安全就会直接将其丢弃,才会出现这样的现象!

解决方案(后端来进行解决):①CORS跨域资源共享。②JSONP

  • 优先使用CORS跨域资源共享,如果浏览器不支持CORS的话,再使用JSONP。


二、两种解决方案

方案1:CORS(IE10及以上选择)

认识CORS以及进行测试

CORS:简而言之就是后端发送响应前,给响应头设置Access-Control-Allow-Origin: *(也可指定单个地址,这里指的是所有地址允许)即可,浏览器接收到响应解析了到就会放行认为其是安全的。

测试

由于需要后端来设置响应头的内容才能够实现CORS,所以这里来使用慕课网的接口来进行测试:https://www.imooc.com/api/http/search/suggest?words=js,这是慕课网的一个关键词接口,我们通过1.1中的ajax来发送请求。

成功响应:

image-20210713214840097

响应头信息:

image-20210713214912231


Access-Control-Allow-Origin说明

兼容性:IE10及以上版本的浏览器可以使用CORS。若是要适配IE10以下的只能使用JSONP。

Access-Control-Allow-Origin: *:表名允许所有的域名来跨域请求它,*是通配符,没有任何限制。

Access-Control-Allow-Origin: http://127.0.0.1:5500:只允许指定域名的跨域请求。(允许单个)

CORS跨域过程(核心重点)

1、浏览器发送请求。

2、后端在响应头中添加Access-Control-Allow-Origin头信息。

3、浏览器接收到响应。

4、如果是同域下的请求(比对发出的请求),浏览器不会额外做任何事情。前后端通信成功!

5、如果是跨域请求(不同域请求),浏览器会从响应头中查找是否允许跨域访问

6、如果允许跨域(根据响应头中的Access-Control-Allow-Origin),前后端通信成功!

7、如果没找到或不包含想要跨域的域名,就会丢弃响应结果。

核心就是如果向不同域的后端发送请求,浏览器在拿到响应结果后会去解析响应头中是否有对应的Access-Control-Allow-Origin,若是该键值对为允许跨域的域名,此时通信成功!



方案2:JSONP(IE10以下选择方案)

实现方式:同样需要后端来实现JSONP,加载JSONP接口需要使用前端的script标签。

浏览器测试

我们依旧使用慕课的一个接口:https://www.imooc.com/api/http/jsonp?callback=handleResponse,其中callback=后面的可以任意设置名称。

image-20210713220454277

此时前端需要通过调用指定后面跟着的函数名得到指定对象!


前端静态与动态加载JSONP接口

静态加载:其中script标签必须放在最后引用才有效

<script>
    // 2、使用指定callback=xxx,后面的xxx函数来接收data对象
    const handleResponse = (data) => {
        console.log(data);
        console.log(typeof data);
    }
</script>
<!-- 1、使用script标签来进行加载资源(必须放置在最后) -->
<script src="https://www.imooc.com/api/http/jsonp?callback=handleResponse"></script>

image-20210713221013378

动态加载:就是使用js来动态创建一个dom元素并将其挂载到dom树上

<script>
    // 1、创建script标签并进行挂载
    var s = document.createElement("script");
    s.src = "https://www.imooc.com/api/http/jsonp?callback=handleResponse";
    document.body.appendChild(s);
    // 2、使用指定callback=xxx,后面的xxx函数来接收data对象
    const handleResponse = (data) => {
        console.log(data);
        console.log(typeof data);
    }
</script>

image-20210713221220874

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。