【问题标题】:How to create cross-domain request?如何创建跨域请求?
【发布时间】:2016-04-19 19:21:08
【问题描述】:

如何使用 Angular 2 创建跨域请求?

你能举个例子吗?
就像 localhost:3000 和 localhost:8000 跨域之间的请求一样

【问题讨论】:

    标签: angular http cors cross-domain


    【解决方案1】:

    在本地chrome浏览器上启用跨域请求的一种方式:

    1. 创建 google chrome 的快捷方式。
    2. 属性 -> 在目标末尾附加“--disable-web-security --user-data-dir”。
    3. 关闭或杀死谷歌浏览器的所有进程。
    4. 重新启动并点击 UI url。

    现在在不同端口上运行的 UI 和 API 将能够协同工作。我希望这会有所帮助。

    如果您正在寻找跨域请求的示例。 我会把它分成片段让你有足够的想法。

    Angular 客户端

    user.service.ts 来调用 SpringWebservice

     /** POST: Validates a user for login from Spring webservice */
          loginUrl = 'http://localhost:8091/SpringWebService/login';  // URL to web api
    
         validUser (user: User): Observable<User> {
            return this.http.post<User>(this.loginUrl, user, httpOptions)
           .pipe(
               catchError(this.handleError('Login User', user))
      );
    }
    
    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type':  'application/json;charset=utf-8',
        'Authorization': 'my-auth-token'
      })
    };
    

    login.component.html:接受用户名和密码。

    <form (ngSubmit)="onSubmit(loginForm)" #loginForm="ngForm">
        <!-- //ngModel is a must for each form-control  -->
      <!-- 1st group -->
      <div class="form-group">
            <label for="name">Name</label>
            <input type="text" class="form-control" id="name" 
                    required name="name"  ngModel #name="ngModel"> 
    
            <div [hidden]="name.valid || name.pristine"
                    class="alert alert-danger">
                 Name is required
            </div>
      </div> 
      <!-- 2nd group -->
      <div class="form-group">
          <label for="pwd">Password</label>
          <input type="text" class="form-control" id="pwd"
                name="pwd" #pwd required ngModel>
      </div>   
    
      <button type="submit" class="btn btn-success" [disabled]="!loginForm.valid">Submit</button>
    
    </form>
    

    login.component.ts:调用并订阅user.service的validUser方法。

    userModel : User;
    onSubmit(loginForm : NgForm) { 
    this.submitted = true; 
    console.log("User : "+loginForm.value.name + " Valid :"+loginForm.valid)
    
    this.userModel.loggedIn= false;
    this.userModel=new 
    User(loginForm.value.name.trim(),loginForm.value.pwd.trim())
    // Passing the userModel to Service method to invoke WebAPI
    this.userService.validUser(this.userModel).subscribe(user=>
        {
          if(user.loggedIn == false){
            console.log("Invalid User/PWD");
    
           }
          else{
            this.userService.changeUser(this.userModel);
            this.router.navigate(['/home']);
          }
      }
    );
    

    user.ts: 模型。

    export class User {
    
    constructor(
        public  name : String,
        public  pwd : String,
        public  email ?: String, //optional
        public  mobile ? : number,//""
        public  loggedIn : boolean = false
    ){  }
    }
    

    Spring Web 服务

    package com.rest;
    
    import org.springframework.web.bind.annotation.CrossOrigin;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    // This annotation opens door for cross-domain(Cross-origin resource sharing (CORS)) from any host
    @CrossOrigin(origins="*") 
    public class MainController {
    
         @RequestMapping(value="/login", method=RequestMethod.POST)
         public User validUser(@RequestBody User user){
    
    
             BaseResponse response = new BaseResponse();
    
             if(user.getName().equalsIgnoreCase("shaz") && user.getPwd().equals("pwd")){
    
                 user.setLoggedIn(true);
             }
             else{
    
                 user.setLoggedIn(false);
    
             }
             return user;
    
         }
    }
    

    现在,当您在表单中将名称传递为“shaz”并将密码传递为“pwd”并点击提交时,它会从 SpringWebService 得到验证,并将已登录标志设置为 true,并返回用户实体作为响应。根据响应中的已登录状态,将用户重定向到主页或抛出错误。

    登录页面和网络详情

    注意:我没有分享完整的设置和代码

    请参考:https://shahbaazdesk.wordpress.com/2018/04/03/angular5-with-spring-webservice/

    【讨论】:

      【解决方案2】:

      根据我的经验,这些插件可以与 http 一起使用,但不能与最新的 httpClient 一起使用。此外,在服务器上配置 CORS 响应标头并不是一个真正的选择。所以,我创建了一个 proxy.conf.json 文件来充当代理服务器。

      在此处了解更多信息:https://github.com/angular/angular-cli/blob/master/docs/documentation/stories/proxy.md

      下面是我的 prox.conf.json 文件

      {
        "/posts": {
          "target": "https://example.com",
          "secure": true,
          "pathRewrite": {
          "^/posts": ""
        },
          "changeOrigin": true
        }
      }
      

      我将 proxy.conf.json 文件放在同一目录中的 package.json 文件旁边

      然后我修改了 package.json 文件中的启动命令,如下所示

      "start": "ng serve --proxy-config proxy.conf.json"
      

      现在,我的应用组件的http调用如下

      return this._http.get('/posts/pictures?method=GetPictures')
      .subscribe((returnedStuff) => {
        console.log(returnedStuff);
      });
      

      最后要运行我的应用程序,我必须使用 npm startng serve --proxy-config proxy.conf.json

      【讨论】:

      • 工作绝对像魅力
      【解决方案3】:

      这里有很多长(且正确)的答案。但通常您不会手动执行这些操作 - 至少在您设置第一个开发项目时不会(这是您通常偶然发现这些事情的地方)。如果你使用 koa 作为后端:使用 koa-cors。通过 npm 安装...

      npm install --save koa-cors
      

      ...并在代码中使用它:

      const cors = require('koa-cors');
      const Koa = require('koa');
      const app = new Koa();
      app.use(cors());
      

      问题解决了。

      【讨论】:

        【解决方案4】:
        @RestController
        @RequestMapping(value = "/profile")
        @CrossOrigin(origins="*")
        public class UserProfileController {
        

        SpringREST 提供 @CrossOrigin 注释,其中 (origins="*") 允许从任何来源访问 REST API。

        我们可以将其添加到各自的 API 或整个 RestController。

        【讨论】:

          【解决方案5】:

          您在客户端无能为力。 我在服务器端的控制器中添加了@CrossOrigin,它可以工作。

          @RestController
          @CrossOrigin(origins = "*")
          public class MyController
          

          请参考docs

          【讨论】:

          • 我不确定 OP 是否询问过 Java、Spring 或 REST 但无论如何,我会添加一个答案,因为:/
          • Spring RestController @CrossOrigin(origins="*") 工作正常。谢谢。您可以添加它@RestController 以允许访问所有 REST API
          • 谢谢老兄..在长时间搜索问题后,您让我微笑。 :)
          【解决方案6】:

          其实,Angular2 中对于跨域请求没有什么可做的。 CORS 是浏览器原生支持的东西。此链接可以帮助您了解其工作原理:

          简而言之,在跨域请求的情况下,浏览器会自动在请求中添加一个Origin头。有两种情况:

          • 简单的请求。如果我们使用 HTTP GET、HEAD 和 POST 方法,则此用例适用。对于 POST 方法,仅支持具有以下值的内容类型:text/plainapplication/x-www-form-urlencodedmultipart/form-data
          • 预检请求。当“简单请求”用例不适用时,会发出第一个请求(使用 HTTP OPTIONS 方法)以检查在跨域请求的上下文中可以做什么。

          所以实际上大部分工作必须在服务器端完成才能返回 CORS 标头。主要的是Access-Control-Allow-Origin一个。

          200 OK HTTP/1.1
          (...)
          Access-Control-Allow-Origin: *
          

          要调试此类问题,您可以使用浏览器中的开发人员工具(网络选项卡)。

          关于 Angular2,只需像任何其他请求一样使用 Http 对象(例如相同的域):

          return this.http.get('https://angular2.apispark.net/v1/companies/')
                     .map(res => res.json()).subscribe(
            ...
          );
          

          【讨论】:

          • CORS is something natively supported by browsers 是我想要的。这意味着如果服务器端工作已经实现,客户端(我)除了测试它之外没有任何事情要做。
          【解决方案7】:

          对我来说,这是另一个问题。这对某些人来说可能是微不足道的,但我花了一段时间才弄清楚。所以这个答案可能对某些人有帮助。

          我将API_BASE_URL 设置为localhost:58577。第一百万次阅读错误消息后,硬币掉了下来。问题在于它说它只支持HTTP 和其他一些协议。我不得不更改 API_BASE_URL 以便它包含协议。所以将API_BASE_URL 更改为http://localhost:58577 效果很好。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-06-15
            • 2015-10-11
            • 2011-10-28
            • 1970-01-01
            相关资源
            最近更新 更多