我正在尝试从HP Alm的REST API中获取一些数据.它适用于小卷曲脚本 - 我得到了我的数据.
现在使用JavaScript,fetch和ES6(或多或少)似乎是一个更大的问题.我一直收到此错误消息:
无法加载Fetch API.对预检请求的响应未通过访问控制检查:请求的资源上不存在"Access-Control-Allow-Origin"标头.因此,不允许来源" http://127.0.0.1:3000 "访问.响应具有HTTP状态代码501.如果不透明响应满足您的需要,请将请求的模式设置为"no-cors"以获取禁用CORS的资源.
我知道这是因为我试图从我的localhost中获取该数据,解决方案应该使用CORS.现在我以为我确实这样做了,但不管怎么说它要么忽略我在标题中写的内容,要么问题是别的什么?
那么,是否存在实施问题?我做错了吗?遗憾的是我无法检查服务器日志.我真的有点卡在这里.
function performSignIn() {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
headers.append('GET', 'POST', 'OPTIONS');
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
fetch(sign_in, {
//mode: 'no-cors',
credentials: 'include',
method: 'POST',
headers: headers
})
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log('Authorization failed : ' + error.message));
}
Run Code Online (Sandbox Code Playgroud)
我正在使用Chrome.我也尝试使用Chrome CORS插件,但后来我收到另一条错误消息:
当请求的凭据模式为"include"时,响应中"Access-Control-Allow-Origin"标头的值不能是通配符"*".因此,不允许来源" http://127.0.0.1:3000 "访问.XMLHttpRequest发起的请求的凭据模式由withCredentials属性控制.
跨源资源共享是一种允许网页将XMLHttpRequests发送到另一个域(来自维基百科)的机制,这非常重要(来自我:).
在过去的几天里,我一直在调整CORS,我想我对一切运作方式都有很好的理解.
所以我的问题不是关于CORS /预检如何工作,而是关于将预检作为新请求类型的原因.我没有看到任何理由为什么服务器A需要向服务器B发送预检(PR)以确定是否接受真实请求(RR) - B当然可以接受/拒绝RR而不用任何先前的公关.
经过相当多的搜索,我在www.w3.org(7.1.5)上找到了这条信息:
为了保护资源免受在此规范存在之前不能源自某些用户代理的跨源请求,进行预检请求以确保资源知道此规范.
我发现这是最难理解的句子.我的解释(应该更好地称之为'最佳猜测')是关于保护服务器B免受来自服务器C的不知道规范的请求.
有人可以解释一个场景/显示PR + RR解决的问题比单独的RR更好吗?
我正在尝试设置AngularJS与跨源资源进行通信,其中传递我的模板文件的资产主机位于不同的域上,因此角度执行的XHR请求必须是跨域的.我已经为我的服务器添加了适当的CORS标头,以便使其工作,但它似乎不起作用.问题是,当我在浏览器(chrome)中检查HTTP请求时,发送到资产文件的请求是OPTIONS请求(它应该是GET请求).
我不确定这是AngularJS中的错误还是我需要配置一些东西.根据我的理解,XHR包装器无法发出OPTIONS HTTP请求,因此看起来浏览器正在试图确定在执行GET请求之前是否"允许"首先下载资产.如果是这种情况,那么我是否还需要使用资产主机设置CORS标头(Access-Control-Allow-Origin:http://asset.host ..)?
所以我在Go中编写这个RESTful后端,它将通过跨站点HTTP请求调用,即来自另一个站点服务的内容(实际上,只是另一个端口,但同源策略启动,所以我们这里) .
在这种情况下,用户代理在某些情况下会发送预检OPTIONS请求,以检查实际请求是否可以安全发送.
我的问题是如何在Go环境中最好地处理和充分响应这些预检请求.我设想的方式并不是很优雅,我想知道是否有其他方法可以解决这个问题.
使用标准net/http包,我可以检查处理程序func中的请求方法,也许是这样的:
func AddResourceHandler(rw http.ResponseWriter, r *http.Request) {
switch r.Method {
case "OPTIONS":
// handle preflight
case "PUT":
// respond to actual request
}
}
Run Code Online (Sandbox Code Playgroud)
我也可以使用Gorilla的 mux包,并为每个相关的URL路径注册预检"OPTIONS"处理程序.
r := mux.NewRouter()
r.HandleFunc("/someresource/item", AddResourceHandler).Methods("PUT")
r.HandleFunc("/someresource/item", PreflightAddResourceHandler).Methods("OPTIONS")
Run Code Online (Sandbox Code Playgroud)
也许对这个问题的回答很简单:是的,这些是你的基本选择.但我认为可能有一些最好的做法,我不知道.
编写良好的HTTP服务器在获得CORS预检(OPTIONS)请求时应返回什么状态代码?
200,204还是其他什么东西?
如果允许原点(并且将设置相应的标题)或不允许(并且CORS标题不会被设置或与原点不匹配),状态代码是否应该不同?
我刚开始使用Cross Origin Resource Sharing并尝试让我的webapp响应CORS请求.我的webapp是在Tomcat 7.0.42上运行的Spring 3.2应用程序.
在我的webapp的web.xml中,我启用了Tomcat CORS过滤器:
<!-- Enable CORS (cross origin resource sharing) -->
<!-- http://tomcat.apache.org/tomcat-7.0-doc/config/filter.html#CORS_Filter -->
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Run Code Online (Sandbox Code Playgroud)
我的客户端(使用AngularJS 1.2.12编写)正在尝试访问启用了基本身份验证的REST端点.当它发出GET请求时,Chrome首先预检请求,但是从服务器收到403 Forbidden响应:
Request URL:http://dev.mydomain.com/joeV2/users/listUsers
Request Method:OPTIONS
Status Code:403 Forbidden
Request Headers:
OPTIONS /joeV2/users/listUsers HTTP/1.1
Host: dev.mydomain.com
Connection: keep-alive
Cache-Control: max-age=0
Access-Control-Request-Method: GET
Origin: http://localhost:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/32.0.1700.107 Safari/537.36
Access-Control-Request-Headers: accept, authorization
Accept: */*
Referer: http://localhost:8000/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Response Headers:
HTTP/1.1 …Run Code Online (Sandbox Code Playgroud) 我正在设计一个API,允许用户进行身份验证(使用令牌)并在同一域中包含重定向.现在,对于返回303的端点的未经身份验证的请求,
GET /documents/123 --> 303 redirect to `/documents/abc`
GET /documents/abc --> 200
Run Code Online (Sandbox Code Playgroud)
一切顺利.
让我们对Authorization发送标头的同一端点进行经过身份验证的请求.这使得请求成为预先请求,并且浏览器执行预检OPTIONS请求,即
OPTIONS /documents/123 --> 204 (everything okay, please proceed)
GET /documents/123 --> 303 redirect to `/documents/abc`
Run Code Online (Sandbox Code Playgroud)
此时,浏览器产生的不是GET实际资源/documents/abc
XMLHttpRequest cannot load http://localhost:8000/people/username/nschloe.
The request was redirected to 'http://localhost:8000/people/YDHa-B2FhMie',
which is disallowed for cross-origin requests that require preflight.
Run Code Online (Sandbox Code Playgroud)
此行为符合标准:
7.1.5带预检的跨源请求
如果响应的HTTP状态代码不在2xx范围内
应用网络错误步骤.
这似乎意味着即使重定向位于同一个域(),也无法对经过身份验证的资源进行重定向localhost.
这真的可以吗?有一个共同的解决方法吗?
我有两个VS项目:一个暴露MVC5控制器,另一个是角客户端.我希望angular客户端能够查询控制器.我阅读了很多线程并尝试了以下内容:
我在服务器的web配置中添加了这个:
<system.webServer>
<httpProtocol>
<customHeaders>
<clear />
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
<system.webServer>
Run Code Online (Sandbox Code Playgroud)我在控制器的动作上创建并使用了以下过滤器:
public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
base.OnActionExecuting(filterContext);
}
}
Run Code Online (Sandbox Code Playgroud)在angular客户端中,我创建了以下拦截器:
app.factory("CORSInterceptor", [
function()
{
return {
request: function(config)
{
config.headers["Access-Control-Allow-Origin"] = "*";
config.headers["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS";
config.headers["Access-Control-Allow-Headers"] = "Content-Type";
config.headers["Access-Control-Request-Headers"] = "X-Requested-With, accept, content-type";
return config;
}
};
}
]);
app.config(["$httpProvider", function ($httpProvider) {
$httpProvider.interceptors.push("CORSInterceptor");
}]);
Run Code Online (Sandbox Code Playgroud)根据Firebug,这导致以下请求:
OPTIONS //Login/Connect HTTP/1.1
Host: localhost:49815
User-Agent: Mozilla/5.0 (Windows NT …Run Code Online (Sandbox Code Playgroud) 我对CORS POST请求的安全性方面有点困惑.我知道网上有关于这个话题的信息丢失了,但我找不到我的问题的明确答案.
如果我理解正确,同源策略的目标是防止CSRF攻击,并且CORS的目标是在(并且仅当)服务器同意与其他站点上托管的应用程序共享其数据时启用资源共享(起源) ).
HTTP指定POST请求不是"安全"的,即它们可能会更改服务器的状态,例如通过添加新注释.当使用HTTP方法POST发起CORS请求时,如果请求的内容类型是非标准的(或者如果存在非标准的http标头),则浏览器仅执行"安全"预检请求.因此,执行带有标准内容类型和标准标头的POST请求,并且可能对服务器产生负面影响(尽管请求脚本可能无法访问响应.)
存在这种向每个表单添加随机令牌的技术,然后服务器需要将其作为每个非安全'请求的一部分.如果脚本试图伪造请求,它也可以
我的结论是,对标准内容类型和标题的伪造POST请求的唯一保护是上述技术(或类似的技术).对于任何其他非安全'请求,例如PUT或DELETE,或具有json内容的POST,使用该技术不是必需的,因为CORS执行'安全'OPTIONS请求.
为什么CORS的作者将这些POST排除在预检请求之外,因此有必要采用上述技术?
有谁知道如何让 Safari 在开发工具网络选项卡中显示 CORS 飞行前选项请求?
IIRC 他们曾经出现过,我知道正在发出请求,因为我们可以看到他们登录服务器。
我们在过去几周(Chrome 79/80 左右)突然出现了同样的问题,不得不通过设置chrome://flags/#out-of-blink-cors来强制它disable
cors ×10
preflight ×10
angularjs ×3
http ×3
ajax ×1
api ×1
asp.net-mvc ×1
cross-domain ×1
fetch-api ×1
go ×1
html5 ×1
javascript ×1
post ×1
redirect ×1
safari ×1
security ×1
spring-mvc ×1
tomcat ×1