【问题标题】:Angular 2 - no access control allow origin header [duplicate]Angular 2 - 没有访问控制允许原始标头[重复]
【发布时间】: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());
}
  1. 调用 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 进行调用,如下面的链接所述:stackoverflow.com/questions/36289495/…
  • @Mukund 您从中调用网页的 URL。它是否也以http://localhost:8080 开头?还是以file:///开头
  • @Chester 它是“localhost:3000

标签: java spring angular typescript


【解决方案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

【讨论】:

    猜你喜欢
    • 2017-08-31
    • 2017-12-27
    • 2017-07-24
    • 2019-10-26
    • 2019-07-09
    • 2022-06-25
    • 2023-03-14
    • 1970-01-01
    • 2020-01-21
    相关资源
    最近更新 更多