No 'Access-Control-Allow-Origin' header is present on the requested resource', 跨域访问的解决方法

1. 当请求不在同一域名下的资源文件(ip地址+端口号)时,会报如下错误:
“No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘http://localhost:8080’ is therefore not allowed access.”,翻译下,因为被请求的资源没有设置 ‘Access-Control-Allow-Origin’,所以 从’http://localhost:8080’ 发起的请求不被允许。

2. 原因:浏览器同源策略限制了此类请求。什么是同源策略?
同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
同源策略限制以下几种行为:
1.) Cookie、LocalStorage 和 IndexDB 无法读取
2.) DOM 和 Js对象无法获得
3.) AJAX 请求不能发送
常见跨域场景
1.)同一域名下的不同文件或路径,允许访问。
http://www.domain.com/a.js
http://www.domain.com/b.js
http://www.domain.com/lab/c.js
2.)同一域名下的不同端口, 不允许访问。
http://www.domain.com:8000/a.js
http://www.domain.com/b.js
3.)同一域名下的不同协议, 不允许访问。
http://www.domain.com/a.js
https://www.domain.com/b.js
4.)同一ip地址下的不同域名之间,不允许访问。
http://www.domain.com/a.js
http://192.168.4.12/b.js
5.) 不同域名之间不允许访问。
http://www.domain1.com/a.js
http://www.domain2.com/b.js

3.解决办法。
1.)针对上面的错误提示,我们肯定可以通过在被请求的资源文件中添加 'Access-Control-Allow-Origin’来解决跨域问题。
(1)如果被请求的是静态HTML文件,则需要只需要在被请求的HTML文件中加上一下标签。

<meta http-equiv="Access-Control-Allow-Origin" content="*" />

(2)如果被请求的是java接口,则可以在响应头中加上:

response.setHeader("Access-Control-Allow-Origin", "http://www.domain1.com"); 

(3)如果被请求的是.net接口,则可以在响应头中加上:

Response.AddHeader("Access-Control-Allow-Origin", "*");

2.)另外一种方法就是从前端解决。前端可以通过jsonp请求的方式或者设置代理的方式解决。
(1)通过jsonp的方式。
跨域原理: 通常为了减轻web服务器的负载,我们把js、css,img等静态资源分离到另一台独立域名的服务器上,在html页面中再通过相应的标签从不同域名下加载静态资源,而被浏览器允许,基于此原理,我们可以通过动态创建script,再请求一个带参网址实现跨域通信。

原生实现:
 <script>
    var script = document.createElement('script');
    script.type = 'text/javascript';

    // 传参并指定回调执行函数为onBack
    script.src = 'http://www.domain2.com:8080/login?user=admin&callback=onBack';
    document.head.appendChild(script);

    // 回调执行函数
    function onBack(res) {
        alert(JSON.stringify(res));
    }
 </script>
jquery实现:
$.ajax({
    url: 'http://www.domain2.com:8080/login',
    type: 'get',
    dataType: 'jsonp',  // 请求方式为jsonp
     crossDomain: true,
	 success: function(data) {},
    data: {}
});

(2)通过请求代理的方式。
跨域原理: 同源策略是浏览器的安全策略,不是HTTP协议的一部分。服务器端调用HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也就不存在跨越问题。
以下提供java/.net跨域文件的源码,请自行发布使用。请求代理文件源码地址:https://github.com/muziye2013/CrossDomainAccessProxy

a. 如果是.NET开发环境,请将下载的“DotNet”源码发布为网站
在这里插入图片描述
并将网站的物理路径,指向源码DotNet地址:
在这里插入图片描述
修改index.html页面中被请求的资源,在浏览器中访问index.html页面进行测试。

 var testUrl="http://172.17.0.130/***/query";//修改测试服务地址

b.如果是Java开发环境,请将下载的“Java”源码放在tomcat网站下的webapps目录下,
在这里插入图片描述
修改index.html页面中被请求的资源,启动tomcat,在浏览器中访问index.html页面进行测试。

以上,推荐使用第三种方式来进行配置,特别是对于前后端分离开发时,一劳永逸的解决跨域问题。

文章参考:https://segmentfault.com/a/1190000011145364

### 解决因缺少 `Access-Control-Allow-Origin` 头而导致的 CORS 错误 CORS(资源共享)是一种用于控制浏览器如何允许网页从不同的源加载资源的安全机制。当服务器响应中未包含必要的 `Access-Control-Allow-Origin` 头时,浏览器会阻止前端应用访问这些资源,并抛出 CORS 错误。 --- #### 为什么会出现此问题? 当客户端(通常是浏览器中的 JavaScript 应用程序)尝试向另一个源(即具有不同协议、名或端口号的服务器)发出 HTTP 请求时,浏览器会在后台执行一系列检查来确认目标服务器是否允许此类请求。如果没有设置适当的 CORS 响应头,例如 `Access-Control-Allow-Origin`,则请求会被拒绝[^7]。 --- #### 如何解决? ##### 方法一:在后端添加 CORS 响应头 最直接的方式是在服务器端配置相应的 HTTP 响应头以支持请求。下面是一些常见编程框架的例子: ###### 对于 Flask: 可以手动为每个路由添加所需的 CORS 响应头。 ```python from flask import Flask, make_response app = Flask(__name__) @app.after_request def add_cors_headers(response): response.headers['Access-Control-Allow-Origin'] = '*' # 允许所有来源 response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE' # 允许的方法列表 response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization' # 允许的头部字段 return response @app.route('/data', methods=['GET']) def get_data(): data = {'key': 'value'} return make_response(data) ``` 此处将 `Access-Control-Allow-Origin` 设定为通配符 (`*`) 表示任何外部站点都可以访问 API 数据;但在涉及敏感信息的情况下应该指定确切的 URL 地址而不是使用星号[^8]。 ###### 对于 Node.js/Express: 同样可以通过中间件实现这一目的。 ```javascript const express = require('express'); const app = express(); // 添加 CORS 支持 app.use((req, res, next) => { res.header("Access-Control-Allow-Origin", "*"); res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); res.header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); next(); }); app.get('/data', (req, res) => { const data = { key: 'value' }; res.json(data); }); ``` --- ##### 方法二:利用反向代理规避 CORS 限制 另一种方法是通过同一源上的反向代理转发请求到实际的服务端点。这样做的好处是可以完全绕过浏览器级别的 CORS 检查,因为所有的通信都发生在同一个主机内部。 假设我们正在运行一个 Nginx 作为我们的 Web 服务器兼反向代理角色,则可以在其配置文件中加入如下内容: ```nginx server { listen 80; server_name localhost; location /api/ { proxy_pass http://backend_server/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } ``` 在这个例子当中,所有发往 `/api/...` 路径下的请求都会被重定向至名为 `backend_server` 的上游服务那里去处理[^9]。 --- ##### 方法三:修改客户端代码 虽然这不是最佳实践,但如果无法更改远程API的行为模式的话,也可以考虑采用JSONP技术或者iframe沙箱等方式间接获取所需的数据。不过需要注意的是这两种方式都有各自的局限性和安全隐患,所以一般只适合非常特殊的情况之下才选用它们[^10]。 --- ### 结论 为了有效应对由于缺乏必要首部而引发的读取失败状况,应当优先调整后端逻辑,在回应消息里附加恰当形式化的权限声明项——主要是指明许可范围内的原始地址以及所接纳的动作类别等内容。与此同时也要留意保护好个人隐私资料免受未经授权方窥探的风险。 ---
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值