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 “没有访问控制允许来源......”

ionic 2 没有“访问控制允许来源”标头

春季网关请求被 CORS 阻止(无访问控制-允许-来源标头)

Angular 2,没有“访问控制允许来源”

Angular 6 - 对预检请求的响应未通过访问控制检查:没有“Access-Control-Allow-Origin”标头

我无法在 Angular 4 上向 laravel api 发送带有标头的 http 请求