Angular 2 - 没有访问控制允许原始标头[重复]
Posted
技术标签:
【中文标题】Angular 2 - 没有访问控制允许原始标头[重复]【英文标题】:Angular 2 - no access control allow origin header [duplicate] 【发布时间】:2018-01-23 18:05:41 【问题描述】:我的项目在后端使用 spring,在前端使用 angular2。我在 spring 项目的 webapp 文件夹下有一个 json 文件。我正在尝试从角度访问它。
只要输入“http://localhost:8080/project1/test.json”就可以访问该文件
但是,如果我使用来自 Angular 的相同链接,我会收到一条错误消息,提示“没有访问控制允许原始标头”
我的角度代码: 1. service.ts中定义的函数getJson():
getJson()
return this.http.get('http://localhost:8080/project1/test.json')
.map((response:Response) => response.json());
调用 getJson():
结果=[];
this._manoService.getJson().subscribe(resJsonData => this.results = resJsonData);
我创建了 proxy.conf.json 并添加了以下几行:
"/project1":
"target": "http://localhost:8080",
"secure": false
并且还在package.json中添加了"start": "ng serve --proxy-config proxy.conf.json",
我仍然遇到同样的问题。我做错什么了吗?
【问题讨论】:
当您调用此页面时,您的 URL 是什么样的? @Chester 我可以知道你问的是哪个网址吗? 使用 jsonp 进行调用,如下面的链接所述:***.com/questions/36289495/… @Mukund 您从中调用网页的 URL。它是否也以http://localhost:8080
开头?还是以file:///
开头
@Chester 它是“localhost:3000”
【参考方案1】:
出于安全原因,浏览器强制使用same origin policy。您的角度页面位于 localhost:8080 以外的来源(很可能是 localhost:3000)。所以浏览器不允许访问。
SOP 是网络的一个非常重要的概念。例如,您可能登录到您的银行帐户,然后打开另一个网站。 SOP 会阻止该网站访问您的银行帐户。
有几种方法可以授予cross origin access。
到目前为止,最简单的方法是将所有内容放在同一个原点上。也就是说,在与生产服务相同的域和端口上提供 Angular 应用程序。对于开发,您可以配置ng serve
充当代理服务器。因此,您将向http://localhost:3000/project1/test.json
提出服务请求,并让ng service
将其转发到 localhost:8080。这在Angular proxy documentation中有详细解释。
如果您甚至在生产中也需要跨源请求,Spring 可以相对容易地允许这样做:您需要使用 @CrossOrigin 注释您的服务方法,如 Spring REST tutorial 中所述。在这种情况下,通过 cookie 进行的身份验证将不再起作用。如果您需要身份验证,您应该查看 oauth。将@CrossOrigin 注释添加到您的服务方法中,将使Spring-REST 添加Access-Control-Allow-Origin
http-header。
使用正确 CORS 的另一种替代方法是使用 jsonp,但这是现在应该避免的黑客行为。 JSONP 利用了这样一个事实,即您可以将<script>
标记包含到任何来源,并下载并执行提供的javascript。所以 JSONP 背后的想法是你定义一个回调函数,服务器将生成并返回 JavaScript 代码,该代码以实际数据作为参数调用这个函数。
【讨论】:
我尝试在 prof.conf.json "/project1": "target": "localhost:8080", "secure": false 中添加以下代码仍然是同样的问题。我做错了什么吗? 您是否将this.http.get
代码行更改为指向localhost:3000?【参考方案2】:
假设该服务由 Spring @RestController
实现,您需要通过运行其余服务的服务器之外的网站来使用它。在这种情况下,只需将 @CrossOrigin
注释添加到处理程序方法即可。
例如(在此示例中,@CrossOrigin
仅对 addSite 处理程序方法启用。
@RestController
public class SiteController
@Autowired
private SiteServiceImpl siteService;
@CrossOrigin(origins = "*")
@RequestMapping(method = RequestMethod.POST, value = "/api/sites")
public void addSite(@RequestBody Site site)
siteService.addSite(site);
但您也可以为整个控制器启用@CrossOrigin
,在@RestController
级别启用@CrossOrigin
。
例如:
@RestController
@CrossOrigin(origins = "*")
public class SiteController
@Autowired
private SiteServiceImpl siteService;
@RequestMapping(method = RequestMethod.POST, value = "/api/sites")
public void addSite(@RequestBody Site site)
siteService.addSite(site);
@CrossOrigin(origins = "*")
注释允许其余服务之外的所有资源使用它,如果该服务仅可用于来自一个特定来源的资源,那么只需将来源值更改为资源所在的服务器名称,例如@CrossOrigin(origins = "http://myothersite.com")
更多相关信息在Spring站点:cors-support-in-spring-framework
【讨论】:
以上是关于Angular 2 - 没有访问控制允许原始标头[重复]的主要内容,如果未能解决你的问题,请参考以下文章
Angular 和 Golang “没有访问控制允许来源......”
春季网关请求被 CORS 阻止(无访问控制-允许-来源标头)
Angular 6 - 对预检请求的响应未通过访问控制检查:没有“Access-Control-Allow-Origin”标头