首页 > 解决方案 > POST 请求不工作,但 GET 工作正常。请求的资源上不存在“Access-Control-Allow-Origin”标头

问题描述

我有一个 POST 和一个 GET 方法,来自请求被触发的同一个域。虽然,我觉得 CORS 不会成为问题,但它似乎是,因为端口不同。

添加标题后,我可以设法处理我的 GET 请求,但 POST 不起作用。

我在服务器端添加了标题,下面是代码:

    @SuppressWarnings("unchecked")
    @RequestMapping(method=RequestMethod.OPTIONS,value="/refer")
    public ResponseEntity<?> options(){
        return new ResponseEntity(getHeaders(), HttpStatus.OK);

    }


    @RequestMapping(method=RequestMethod.GET,value="/search",produces="application/json")
    public ResponseEntity<?> searchCook(@ModelAttribute("cookSearch") CookSearch cookSearch){

        ResponseDto<List<DtoCook>> response = new ResponseDto<>();
        List<DtoCook> results = serviceCook.search(cookSearch);
        response.setData(results);
        response.setMessage(results.size()+" found.");
        return new ResponseEntity<>(response, getHeaders(),HttpStatus.OK);

    }


    @SuppressWarnings("unchecked")
    @RequestMapping(method=RequestMethod.POST,value="/refer",produces="application/json",consumes="application/json")
    public ResponseEntity<?> referCookPost(@ModelAttribute("dtoCookRefer") DtoCookRefer dtoCookRefer,BindingResult result) {

        System.out.println("in cook rest controller");

        // set the headers to allow CORS
        MultiValueMap<String, String> headers = getHeaders();

        System.out.println(dtoCookRefer.getCookName()+ " phone");
        ResponseDto<DtoCookRefer> respDto = new ResponseDto<>();
        respDto.setData(dtoCookRefer);

        //run Spring validator manually
        new CookReferValidator().validate(dtoCookRefer, result);

        if(serviceCookRefer.checkUniquePhNum(dtoCookRefer)) {
            respDto.setMessage("Phone number already present");
            return new ResponseEntity<>(respDto, headers,HttpStatus.UNPROCESSABLE_ENTITY);
        }


        // validate cook data
        if(result.hasErrors()) {
            //TODO set message source
            respDto.setMessage("Improper data");
            return new ResponseEntity<>(respDto, headers,HttpStatus.UNPROCESSABLE_ENTITY);


        }else {
            // save data to database
            serviceCookRefer.referCook(dtoCookRefer);
            // return proper response
            respDto.setMessage("Processed Successfully");
            return new ResponseEntity(respDto, headers, HttpStatus.OK);
        }


    }

    private MultiValueMap<String, String> getHeaders(){

        MultiValueMap<String, String> headers = new LinkedMultiValueMap<String,String>();
        headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
        headers.add("Pragma", "no-cache");
        headers.add("Expires", "0");
        headers.add("Access-Control-Allow-Origin","http://example.org");
        headers.add("Access-Control-Allow-Methods","GET,PUT,POST,DELETE,OPTIONS");
        headers.add("Access-Control-Allow-Headers", 
                "Cache-Control,Pragma,Expires,Access-Control-Allow-Origin,"
                + "Access-Control-Allow-Methods,Content-Type,Transfer-Encoding,Date");
        return headers;
    }

下面是 Angular 中的代码:

import { Injectable } from '@angular/core';
import {HttpClient, HttpHeaders} from '@angular/common/http';
import { CookRefer } from './cook-refer';

@Injectable({
  providedIn: 'root'
})
export class CookReferService {
  private _url : string = "http://123.121.166.243:8080/ffc/ext/cook/refer";
  constructor(private _http : HttpClient) { }

  headers = new HttpHeaders({
    'Content-Type':'application/json',
    'Access-Control-Request-Method':'POST'
  });

  options={headers:this.headers};

  
  refer(cook : CookRefer){
    return this._http.post<any>(this._url,cook,this.options);
  }
}
我什至添加了一个 OPTIONS 方法,但没有帮助。我不确定是否有必要。我需要以下几点帮助:

标签: angularspringrestcors

解决方案


可能您应该在允许的标题中添加标题 Access-Control-Request-Method ,添加到您的发布请求中。

尝试在您的控制器上使用 CrossOrigin 注释,而不是添加选项方法,或者如果您只想允许 CORS 用于一种方法,则可以在您的方法上使用:

@CrossOrigin
@RestController
public class Controller {

    // @CrossOrigin
    @RequestMapping("/link")
    public String retrieve() {
       // ...
    }
}

您还可以从控制器中进行全局 Cors 配置,例如:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

推荐阅读