laravel Angular2 标头
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34404638/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular2 Headers
提问by Shaddow
When I call server without headers its working and server returns json:
当我调用没有标头的服务器时,它的工作和服务器返回 json:
this.http.get(url)
but when I add header:
但是当我添加标题时:
var headers = new Headers({'x-id': '1'});
this.http.get(url, {'headers': headers})
browser returns error:
浏览器返回错误:
XMLHttpRequest cannot load http://domain/api/v1/. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
I also tried add Origin
header - browser error: Refused to set unsafe header "Origin"
我也尝试添加Origin
标题 - 浏览器错误:Refused to set unsafe header "Origin"
And Access-Control-Allow-Origin
header - no effect
和Access-Control-Allow-Origin
标题 - 没有效果
On server (Laravel) I created middleware Cors.php
:
在服务器(Laravel)上,我创建了中间件Cors.php
:
<?php
namespace App\Http\Middleware;
use Closure;
class Cors {
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', 'http://localhost:3000')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', 'x-id');
}
}
Im new to angular2 and CORS requests, dont know what to do.
我是 angular2 和 CORS 请求的新手,不知道该怎么做。
- Angular: 2.0.0-beta.0
- Laravel: 5.0
- Browser: Google Chrome
- 角度:2.0.0-beta.0
- Laravel:5.0
- 浏览器:谷歌浏览器
回答by Thierry Templier
A preflighted request with CORS means that an OPTIONS HTTP request is executed before the actual one. You switch from a simple request to the one since you add a custom header in the case of a GET method. This link could help you to understand what happens: http://restlet.com/blog/2015/12/15/understanding-and-using-cors/.
带有 CORS 的预检请求意味着在实际请求之前执行 OPTIONS HTTP 请求。由于在 GET 方法的情况下添加了自定义标头,因此您可以从简单请求切换到请求。此链接可以帮助您了解会发生什么:http: //restlet.com/blog/2015/12/15/understanding-and-using-cors/。
FYI the Origin
header is automatically added by the browser when executing a cross domain request.
仅供参考,Origin
在执行跨域请求时,浏览器会自动添加标头。
I think your problem is within the Access-Control-Allow-Origin
header. You must set the host that makes the call and not the address of the server. You should have this instead (if your Angular2 application is running on localhost:8080
):
我认为您的问题在Access-Control-Allow-Origin
标题内。您必须设置进行调用的主机而不是服务器的地址。您应该使用它(如果您的 Angular2 应用程序正在运行localhost:8080
):
return $next($request)
->header('Access-Control-Allow-Origin', 'http://localhost:8080')
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', 'x-id');
Hope it helps you, Thierry
希望对你有帮助,蒂埃里
回答by Matteo Tosi
I had the same issue in my Angular2 application. The problem, as already stated, is that before every request made by the client a preflight requestis sent to the server.
我在 Angular2 应用程序中遇到了同样的问题。如前所述,问题是在客户端发出每个请求之前,都会将预检请求发送到服务器。
This kind of request have a type OPTIONS, and it's duty of the server to send back a preflight responsewith status 200 and headers set for accepting requests from that client.
这种请求有一个类型OPTIONS,服务器有责任发回状态为 200的预检响应,并设置为接受来自该客户端的请求的标头。
This is my solution (with express):
这是我的解决方案(使用快递):
// Domain you wish to allow
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'YOUR-CUSTOM-HEADERS-HERE');
// Set to true if you need the website to include cookies in requests
res.setHeader('Access-Control-Allow-Credentials', true);
// Check if Preflight Request
if (req.method === 'OPTIONS') {
res.status(200);
res.end();
}
else {
// Pass to next layer of middleware
next();
}
In this way, the client will be authorized and you will be able to set your custom headers in all the requests. In your case, you'll have to set x-idin the Access-Control-Allow-Headersoption.
这样,客户端将获得授权,您将能够在所有请求中设置自定义标头。在您的情况下,您必须在Access-Control-Allow-Headers选项中设置x-id。
回答by Daniel Gartmann
In your case the server has to respond to the preflight request with following headers:
在您的情况下,服务器必须使用以下标头响应预检请求:
Access-Control-Allow-Origin:*
X-Custom-HeaderAccess-Control-Allow-Methods:GET, POST, PUT, DELETE
Access-Control-Allow-Headers: x-id
访问控制允许来源:*
X-Custom-HeaderAccess-Control-Allow-Methods:GET, POST, PUT, DELETE
访问控制允许标题:x-id
Note that for the Access-Control-Allow-OriginHTTP header it's best practice to set the domain where the angular2 app is hosted explicitly instead of the * which is only necessary for public API's where you don't control all consumers!
请注意,对于Access-Control-Allow-OriginHTTP 标头,最佳做法是设置显式托管 angular2 应用程序的域,而不是 * ,这仅对您无法控制所有使用者的公共 API 是必需的!
I highly recommend you to read following article about CORS:
我强烈建议您阅读以下有关 CORS 的文章:
回答by OrbitalSloth
I have been developing an angular2
app with a c# web api
back end and ran into an issue with the cors
settings as well.
我一直在开发一个angular2
带有c# web api
后端的应用程序,但也遇到了cors
设置问题。
The real problem turned out not to be the cors
settings, rather the data that was being sent to the api (js date object to c# datetime type didn't line up correctly). However in your case, is it absolutely essential to pass the x-id in the header rather than as a parameter on the request? For example you could do somthing like this:
真正的问题不是cors
设置,而是发送到 api 的数据(js date 对象到 c# datetime 类型没有正确排列)。但是,在您的情况下,在标头中传递 x-id 而不是作为请求中的参数是绝对必要的吗?例如,你可以做这样的事情:
getYourDataType(id: number): Observable<YourDataType> {
return this.http.get(url + '/' + id.toString())
.map((response: Response) => <YourDataType>response.json());
From my research after dealing with this issue it seems like angular
would try to find the endpoint you were trying to hit, fail to find it and then assume that the reason must be something wrong with the cors settings, rather than the client side data.
从我处理这个问题后的研究来看,它似乎angular
会尝试找到您试图点击的端点,但找不到它,然后假设原因一定是 cors 设置有问题,而不是客户端数据有问题。
You said that the api returns data when you don't set any headers on your request, so if changing from a header to a parameter doesn't work, you could try inspecting the request with a tool like fiddler or the network tab of chrome's dev tools and see if angular constructed each request as you expect it should have. Or comparing the results by manually constructing a request in fiddler, it could be very illuminating as to what exactly is happening to give you this unexpected response.
您说当您没有在请求中设置任何标头时,api 会返回数据,因此如果从标头更改为参数不起作用,您可以尝试使用 fiddler 或 chrome 的网络选项卡之类的工具检查请求开发工具并查看 angular 是否按照您的预期构建了每个请求。或者通过在 fiddler 中手动构建请求来比较结果,它可能会非常清楚究竟发生了什么给您这种意外响应。
At any rate figuring out that there is an issue with your data, rather than the cors
settings is quite difficult. Angular
has you looking at the totally wrong thing trying to figure out a very simple problem. I hope this helps somebody.
无论如何,找出您的数据而不是cors
设置有问题是相当困难的。Angular
您是否在试图找出一个非常简单的问题时看到了完全错误的事情。我希望这对某人有帮助。
回答by Akhilesh Kumar
Try following code, This should work
尝试以下代码,这应该有效
let headers = new Headers();
headers.append('Accept', 'application/json');
headers.append('Content-Type', 'application/json');
headers.append('x-id','1');
this.http.get(url, {'headers': headers}).subscribe(
response => {...},
error => {...}
);
回答by G.T.
the problem is that you also need to set the allowed headers. That's why it's not working. To make it work with a simple angular2 http request, you need to add the following headers:
问题是您还需要设置允许的标题。这就是它不起作用的原因。要使其与简单的 angular2 http 请求一起工作,您需要添加以下标头:
header('Access-Control-Allow-Origin: *');
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept"); // In your case also add x-id or what you are also using.
header('Access-Control-Allow-Methods: POST, PUT, DELETE, GET, OPTIONS');