Angular 2 - 没有访问控制允许原始标题

时间:2017-08-15 18:34:51

标签: java spring angular typescript

我的项目在后端使用弹簧,在前端使用angular2。我在spring项目的webapp文件夹下有一个json文件。我试图从角度访问它。

如果我只输入" http://localhost:8080/project1/test.json"

,我就可以访问该文件

但是,如果我使用角度相同的链接,我收到一条错误消息说"没有访问控制允许原始标题"

我的角度代码: 1.函数getJson()在service.ts中定义:

 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);

  2. 我创建了proxy.conf.json并添加了以下行:

    {
     "/project1": {
     "target": "http://localhost:8080",
     "secure": false
       } 
    }
    

    还添加了" start":" ng serve --proxy-config proxy.conf.json", to package.json

    我仍然遇到同样的问题。我做错了吗?

2 个答案:

答案 0 :(得分:0)

出于安全考虑,浏览器会强制执行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允许相对容易:您需要使用@ Spring REST tutorial中的说明使用@CrossOrigin注释您的服务方法。在这种情况下,通过cookie进行身份验证将不再起作用。如果您需要身份验证,您应该查看oauth。将@CrossOrigin注释添加到服务方法中,将使Spring-REST添加Access-Control-Allow-Origin http-header。

使用适当的CORS的另一种方法是使用jsonp,但这是一个现在应该避免的黑客攻击。 JSONP利用了这样一个事实:您可以在任何来源中包含<script>标记,并且下载并执行提供的javascript。所以JSONP背后的想法是你定义一个回调函数,服务器将生成并返回调用此函数的JavaScript代码,并将实际数据作为参数。

答案 1 :(得分:0)

我们假设该服务是由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向整个控制器启用@CrossOrigin@RestController

例如:

@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