摘要:这里只讲解了两种常见的跨域方式,因为存在一些弊端,因此推荐使用等方式来解决跨域问题。
一、什么是 AJAX 跨域问题
同源策略规定,AJAX 请求(XMLHttpRequest)只能发给同源的网址,否则就会出错。所谓的同源策略是指 3 个相同:协议相同、域名相同、端口相同。
比如 http://www.example.com/index.html 这个网址,协议是http ,域名是 www.example.com,端口是默认的 80。如果你在这个网站上使用 AJAX 发送 http://www.example1.com/index.html 请求,就会出错,因为域名不同。
AJAX 跨域的根本原因是浏览器不允许这么做(不是服务端的问题),浏览器限制 AJAX 跨域请求的目的是为了保证用户信息的安全,防止数据被恶意获取。
二、JSONP 解决跨域问题2.1 JSONP 如何解决跨域问题
AJAX 请求非同源资源会发生跨域问题,但是有的 HTML 标签支持非同源请求,举例来说: 与 标签
使用 JSONP 解决跨域问题,有一种方法,前端以 同样的方式发送请求,把返回的 JSON 数据封装,然后以 JS 脚本形式返回
JSONP 允许客户端传递一个 callback 参数请求跨域服务端,服务端返回数据时用 callback 参数名作为返回的函数名来包裹住返回的 JSON 数据
2.2 JSONP 示例
这里我们以 MOOC 网为例,当访问 https://www.imooc.com/ 时,会发送一个 https://www.imooc.com/index/getstarlist AJAX 请求,下面是访问后返回的 JSON 数据。
我们以 JONP 的形式(https://www.imooc.com/index/getstarlist?callback=test )访问。
2.3 JSONP 的弊端
需要在后端改动代码,比如在 Spring 后台代码中需要配置一个 AbstractJsonpResponseBodyAdvice 切面,不过现在这个类已经过时了,也就是说现在不推荐使用 JSONP 来解决跨域问题
JSONP 默认只支持 GET 方式的请求
发送的不是 XMLHttpRequest 请求(script),所以不支持异步事件等,不过这也是为什么 JSONP 可以解决跨域问题的原因
三、CORS 解决跨域问题CORS 跨资源共享(Cross-origin resource sharing)是一种机制,它通过添加 HTTP 头信息,解决 AJAX 跨域资源访问问题。
CORS 请求可以分为两类:简单请求与非简单请求,主要区别是非简单请求在进行访问之前,会发送一个预检请求。“预检”请求首先通过 OPTIONS 方法向另一域上的资源发送HTTP请求,以便确定实际请求是否安全发送。为了防止每次非简单请求之前都发送预检请求,可以在服务端设置预检请求的缓存的时间。
3.1 简单请求
请求方法为 HEAD、GET、POST 中的 1 种
请求的 header 中没有自定义的请求头
Content-Type 为以下几种:application/x-www-form-urlencoded、multipart/form-data、text/plain
3.2 非简单请求
header 中包含自定义请求头 的 AJAX 请求
PUT、DELETE 形式的 AJAX 请求
Content-Type 字段的类型是 application/json 等
我自己在本地写了一个测试跨域的 demo(Spring Boot),通过端口 8082 发出请求(携带自定义的请求头)访问端口为 8081 的服务。下面是 Chrome 控制台有关 HTTP 的控制信息。
通过上面的图可以看出 CORS 解决跨域问题的关键所在,添加必要的请求头与响应头信息,下面是有关的头信息介绍。
3.3 HTTP 响应首部字段
Access-Control-Allow-Origin:指定了允许访问该资源的外域 URI。对于不需要携带身份凭证的请求,服务器可以指定该字段的值为通配符,表示允许来自所有域的请求。
Access-Control-Allow-Methods:指明了实际请求所允许使用的 HTTP 方法
Access-Control-Expose-Headers:在跨域访问时,XMLHttpRequest 对象的getResponseHeader() 方法只能拿到一些最基本的响应头,如果要携带自定义的请求头,需要在该首部中进行允许的请求头放入白名单
Access-Control-Max-Age:非简单请求预检命令的最大缓存时间,在缓存时间内,对于非简单请求,不会再发送预检请求
Access-Control-Allow-Credentials:是否允许携带身份凭证(Cookie)的请求
3.4 HTTP 请求首部字段
Origin:表明预检请求或实际请求的源 URL
Access-Control-Request-Method:用于预检请求。其作用是,将实际请求所使用的 HTTP 方法告诉服务器
Access-Control-Request-Headers:用于预检请求。其作用是,将实际请求所携带的首部字段告诉服务器
四、other能解决跨域的方式还有很多,比如禁止浏览器的跨域、Nginx 解决跨域等。这里只讲解了两种常见的跨域方式,因为 JSONP 存在一些弊端,因此推荐使用 CORS 等方式来解决跨域问题。
跨域问题,涉及到很多有关 HTTP 协议 的知识,希望大家重视计算机基础知识。上面那个测试的 demo 上传到了 GitHub,demo 是用 Spring Boot 实现的,有需要的可以点我前往~
参考资料跨域资源共享 CORS 详解l
【原创】说说JSON和JSONP,也许你会豁然开朗,含jQuery用例
Cross-Origin Resource Sharing (CORS)
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/98165.html
摘要:如何利用网页请求暴露出来的接口去抓取网页数据很多爬虫都能实现这个功能。跨域通信时,浏览器会报如下错误其实这两个问题都是由于跨域造成的。结果这些数据可以在请求成功会传回本地。 如何利用网页ajax请求暴露出来的接口去抓取网页数据?很多爬虫都能实现这个功能。不过今天要来和大家八一八单从前端的角度,利用js解决这个问题。 大家都知道,在不同域的情况下是不能发送ajax请求的,浏览器会报如下错...
摘要:中间部分由或多个以,分隔的关键字值对构成,关键字字符串和值之间以分隔数组结构以开始,结束。 Q:AJAX以何种格式来交换数据?跨域的需求如何解决? A:用JSON来传数据,靠JSONP来跨域(具体参见下文) AJAX 创建对象 AJAX = Asynchronous(英[eɪˈsɪŋkrənəs]) JavaScript and XML(异步的 JavaScript 和 XML)。...
摘要:数据仍然是通过页面获得,页面仅需向页面传递即可,页面拿到函数名,并通过传递从服务器拿到的数据,在页面执行页面的回调函数,回调函数执行完毕后移除页面以及该函数。以上是我所知道的解决跨域请求的两种方法。 iframe跨域的基本前提是,一个页面可以嵌套非同源站点的html文件,以及某一个域名下的html页面可以通过脚本向同域名服务器发出ajax请求。当一个域名为domain1下的页面A想要向...
摘要:前言中新增了一种数据请求的方式,就是,它和有许多相似的功能,但是相比被设计成更具可扩展性和高效性。该模式支持跨域请求,顾名思义它是以的形式跨域当然该模式也可以同域请求不需要后端额外的支持其对应的为。 前言 ES6中新增了一种HTTP数据请求的方式,就是fetch,它和XMLHttpRequest有许多相似的功能,但是相比XMLHttpRequest,fetch被设计成更具可扩展性和高效...
阅读 3345·2023-04-25 14:07
阅读 3368·2021-09-28 09:35
阅读 2056·2019-08-30 15:55
阅读 1365·2019-08-30 13:48
阅读 2479·2019-08-30 13:16
阅读 3158·2019-08-30 12:54
阅读 3215·2019-08-30 11:19
阅读 1843·2019-08-29 17:17