如果浏览器不能执行其他网站的脚本的问题。那无疑遇到了跨域问题(嘘!!!这里详细解说CORS和JSONP解决跨域问题)

179 阅读5分钟

首先,如果在你的网站上无法加载某个外站URL的资源,但是直接使用浏览器访问该URL却能够畅通无阻,那么你大概率遇到了 CORS 问题。

可以按 F12 打开开发者工具,选择网络 (Network) 选项卡,按 Ctrl + F5 刷新网页,找到出现问题的文件。如果显示为红色且错误码为 "CORS 错误" "CORS Policy" "CORS error" 等,即代表该文件是由于 CORS 问题而无法加载。

什么是 CORS跨域问题

跨源资源共享 (CORS)(或通俗地译为跨域资源共享)是一种基于 HTTP 头的机制,该机制通过允许服务器标示除它以外的其它origin(域,协议和端口),这样浏览器可以访问加载这些资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的"预检"请求。在预检中,浏览器发送的头中标示有HTTP方法和真实请求中会用到的头。当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。而CORS 允许浏览器向跨源服务器,发出跨域请求,从而克服了AJAX只能同源使用的限制。

 

修复 CORS跨域问题********

方法一:
在CDN端添加 HTTP 响应头(推荐)

以华为云CDN为例:打开CDN控制台 ==> 域名管理 ==> 选择你的外链服务器域名 ==> 高级配置 ==> HTTP header 配置 ==> 编辑,在其中设置Access-Control-Allow-Origin属性,并刷新CDN和本地缓存。

方法二:
在服务器端修改配置文件(不推荐)

在你的外链服务器的配置文件里添加以下代码 (宝塔面板在网站 ==> 选择你的外链站 ==> 配置文件,添加到适当位置),之后刷新CDN缓存 (如有):

add_header 'Access-Control-Allow-Origin' *;

需要注意的是,如果你有其他替代方案 (例如你拥有CDN),那么请优先选择该替代方案,因为在服务器端允许跨站可能会招致跨站攻击。如果你需要在服务器端修改,请一定要只允许你必要的格式,不要开放所有格式。

方法三:
迁移到不跨域的静态文件夹(不推荐)

该方法即直接在不跨域的服务器中放置一个文件夹,并单独设置CDN规则。例如,直接在你的文件根目录新建一个 /demo 文件夹,并在你的CDN ==> 缓存设置 中为其单独配置你的缓存方法。

这种解决方案比较万能,可谓是纯纯摆烂了,实现简单、虚拟主机也能做到,但是缺点在于难以管理 (你总不能把整个 WordPress NTP到本地吧),也不利于动静态分离管理。所以,如果你的独立图床拥有CDN,建议先试试方法一。

 

什么是 JSONP 跨域问题

浏览器是允许像 link、img、script 标签在路径上加载一些内容进行请求,是允许跨域的,那么 jsonp 的实现原理就是在 script 标签里面加载了一个链接,去访问服务器的某个请求,返回内容。相比上面 CORS 模块,JSONP 只支持 GET 请求,显然是没有 CORS 模块强大的。

当我们正常地请求一个JSON数据的时候,服务端返回的是一串 JSON类型的数据,而我们使用 JSONP模式来请求数据的时候服务端返回的是一段可执行的 JavaScript代码。因为jsonp 跨域的原理就是用的动态加载 script的src ,所以我们只能把参数通过 url的方式传递,所以jsonp的 type类型只能是get示例:

使用JSONP 模式来请求数据的整个流程:客户端发送一个请求,规定一个可执行的函数名(这里就是 jQuery做了封装的处理,自动帮你生成回调函数并把数据取出来供success属性方法来调用,而不是传递的一个回调函数),服务器端接受了这个 backfn函数名,然后把数据通过实参的形式发送出去.

Snipaste_2023-05-04_18-32-06.png

(在jquery 源码中, jsonp的实现方式是动态添加script标签来调用服务器提供的 js脚本。jquery 会在window对象中加载一个全局的函数,当script代码插入时函数执行,执行完毕后就 script会被移除。同时jquery还对非跨域的请求进行了优化,如果这个请求是在同一个域名下那么他就会像正常的 Ajax请求一样工作。) JSONP跨域与CORS 跨域的区别是:

JSONP浏览器支持较好; CORS不支持IE9及以下浏览器。

JSONP只支持GET; CORS支持所有类型的HTTP请求。

JSONP只发一次请求; CORS复杂请求CORS发送两次。

JSONP(JSON with padding),是一种利用HTML中元素标签,远程调用json文件来实现数据传递的技术,它的特点是可以跨域读取数据。

CORS(Cross-Origin Resource Sharing 跨来源资源共享),CORS允许浏览器向跨域服务器发出XmlHttpRequest请求,简而言之,CORS与JSONP的区别:CORS是JSONP的升级版,JSONP只能通过get方式请求,CORS支持get和post请求。