简体   繁体   English

Spring 启动 CORS

[英]Spring Boot CORS

I am attempting to run Spring Boot and set up my RestConroller to return json to my angular project.我正在尝试运行 Spring Boot 并设置我的 RestConroller 以将 json 返回到我的 angular 项目。 I have added @CrossOrigin(origins = " ", allowedHeaders = " ") at the class level but my website still returns the following error.我在 class 级别添加了 @CrossOrigin(origins = " ", allowedHeaders = " ") 但我的网站仍然返回以下错误。

Essentially I am trying to get a Angular app running in my S3 bucket to connect to a Spring Boot App running in a Kubernetes pod to run Kafa Producer and Consumer stuff.本质上,我试图让在我的 S3 存储桶中运行的 Angular 应用程序连接到在 Kubernetes pod 中运行的 Spring 引导应用程序以运行 Kafa 生产者和消费者的东西。 When I run my Kafka and Spring and Angular all locally (on different ports) it all works, however when I try to get this working in my S3 and in my containers it fails with the corrs error below.当我在本地(在不同的端口上)运行我的 Kafka 和 Spring 和 Angular 时,它都可以工作,但是当我尝试在我的 S3 和我的容器中让它工作时,它会失败并出现下面的 corrs 错误。 Because this is for a school project I don't care about getting the specifics of the corrs security right, I just want it to allow everything so I can prove my Kafa stuff works on the Spring side when I submit data through my Angular app.因为这是一个学校项目,我不关心获得 corrs 安全性的细节,我只希望它允许一切,所以当我通过我的 Angular 应用程序提交数据时,我可以证明我的 Kafa 东西在 Spring 端有效。

Corrs error更正错误

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://<IPADDR>:8080/survey-submit. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://<IPADDR>:8080/survey-submit. (Reason: CORS request did not succeed).

ERROR 
{…}
​
error: error { target: XMLHttpRequest, isTrusted: true, lengthComputable: false, … }
​
headers: Object { normalizedNames: Map(0), lazyUpdate: null, headers: Map(0) }
​
message: "Http failure response for http://<IPADDR>:8080/survey-submit: 0 Unknown Error"
​
name: "HttpErrorResponse"
​
ok: false
​
status: 0
​
statusText: "Unknown Error"
​
url: "http://<IPADDR>:8080/survey-submit"

Survey Form Code for Angular Angular 的调查表代码

import { Component, OnInit } from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs';

import {FormArray, FormBuilder, FormControl, FormGroup, Validators} from '@angular/forms';
import {Router} from '@angular/router';

@Component({
  selector: 'app-survey',
  templateUrl: './survey.component.html',
  styleUrls: ['./survey.component.css']
})

export class SurveyComponent implements OnInit {
    private surveyForm: FormGroup;
    private likeBest: Array<String> = ['Students', 'Location', 'Campus', 'Atmosphere', 'Dorms', 'Sports'];
    private  selectedBest = [];
    private response: string;

    constructor(private http: HttpClient, private _fb: FormBuilder, private router: Router) {

        this.surveyForm = new FormGroup({
            firstName: new FormControl(),
            lastName: new FormControl(),
            addrStreet: new FormControl(),
            addrCity: new FormControl(),
            addrState: new FormControl(),
            addrZip: new FormControl(),
            phone: new FormControl(),
            email: new FormControl(),
            date: new FormControl(),
            likeBest: this.addLikeBest(),
            howHeard: new FormControl(),
            recommendLikelihood: new FormControl()
        });
  }

  addLikeBest() {
        const  arr = this.likeBest.map(e => {
            return this._fb.control(false)
        })
     return this._fb.array(arr);
  }

  get likeBestAry() {
        return <FormArray>this.surveyForm.get('likeBest')
  }

    getSelectedBestValues() {
        this.selectedBest = [];
        this.likeBestAry.controls.forEach((control, i) => {
            if (control.value) {
                this.selectedBest.push(this.likeBest[i])
            }
        })
    }

  ngOnInit(): void {
  }

  private postData() {
     console.log(this.selectedBest)
    const inputData = {
                   nameFirst: this.surveyForm.value.firstName,
                   nameLast: this.surveyForm.value.lastName,
                   addrStreet: this.surveyForm.value.addrStreet,
                   addrCity: this.surveyForm.value.addrCity,
                   addrState: this.surveyForm.value.addrState,
                   addrZip: this.surveyForm.value.addrZip,
                   phone: this.surveyForm.value.phone,
                   email: this.surveyForm.value.email,
                   date: this.surveyForm.value.date,
                   likeBest: this.selectedBest.join(),
                   howHeard: this.surveyForm.value.howHeard,
                   recommendLikelihood: this.surveyForm.value.recommendLikelihood
    }

    this.http.post<any>('http://<IPFORSPRINGBOOTCONTAINER>:8080/survey-submit', inputData).subscribe({
      next: data => {
        console.log("test " + data);
        this.response = 'Item Saved.';
      }
    })
  }
}

Spring Boot Kafka Configurations Spring 引导 Kafka 配置


import edu.swe645.walton.hw1.model.Survey;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.core.*;
import org.springframework.kafka.support.serializer.JsonSerializer;

import java.util.HashMap;
import java.util.Map;

@Configuration
public class KakfaConfiguration {

    Logger logger = LoggerFactory.getLogger("KakfaConfiguration.class");

    @Bean
    public ProducerFactory<String, Survey> producerFactory() {
        Map<String, Object> config = new HashMap<>();
        try {
            config.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "<KAFKAIP>:31852");
            config.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
            config.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);


        } catch (Exception e){
            logger.error("Error in class KakfaConfiguration, Method producerFactory, Message - " +e.getMessage());
        }
        return new DefaultKafkaProducerFactory<>(config);
    }


    @Bean
    public KafkaTemplate<String, Survey> kafkaTemplate() {
        return new KafkaTemplate<>(producerFactory());
    }

    @Bean
    public ConsumerFactory<String, String> consumerFactory() {
        Map<String, Object> config = new HashMap<>();
        try {
            config.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "<KAFKAIP>:31852");
            config.put(ConsumerConfig.GROUP_ID_CONFIG, "group_id");
            config.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
            config.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
        }
        catch (Exception e){
            logger.error("Error in class KafkaConfiguration, Method consumerFactory, Message - " + e.getMessage());
        }
        return new DefaultKafkaConsumerFactory<>(config);
    }


    @Bean
    public ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory() {
        ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory();
        factory.setConsumerFactory(consumerFactory());
        return factory;
    }



}

Spring Boot Controller Spring 启动 Controller

package edu.swe645.walton.hw1.resource;

import edu.swe645.walton.hw1.listner.KafkaConsumer;
import edu.swe645.walton.hw1.model.Survey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@Configuration
@CrossOrigin(origins = "*", allowedHeaders = "*")
public class SurveyResource {
    @Autowired
    private KafkaTemplate<String, Survey> kafkaTemplate;

    @Autowired
    private KafkaConsumer myTopicConsumer;
    Logger logger = LoggerFactory.getLogger("SurveyResource.class");

    private static final String TOPIC = "survey-data-topic";
    private int keyCounter = 0;

    @PostMapping(path="/survey-submit")
    public void postSurvey(@RequestBody Survey s)
    {
        try {
            kafkaTemplate.send(TOPIC, "mykey" + ++keyCounter, s);
        }
        catch (Exception e){
            logger.error("Error in class SurveyResource, Method postSurvey, Message - " + e.getMessage());
        }
    }

    @GetMapping(path="/old-surveys", produces = "application/json")
    public List<Survey> getMessages() {
        return myTopicConsumer.getMessages();
    }
}

EDIT: I'm now getting this....编辑:我现在得到这个.... 在此处输入图像描述

I see this in Chrome我在 Chrome 中看到了这个在此处输入图像描述

You can add that as a filter like given below您可以将其添加为过滤器,如下所示

@Component
public class CORSAllowFilter implements Filter {


    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");    
        chain.doFilter(req, response);
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM