OPTIONS API在应用程序第一次加载到服务器上时只被调用一次

huangapple go评论65阅读模式
英文:

OPTIONS API is only getting called once when Application is loaded for first time on server

问题

以下是您要翻译的内容:

OPTIONS API仅在我第一次启动服务器时以200状态代码调用一次,如果我再次刷新页面,只会调用GET API,或者如果我停止服务器然后重新启动服务器,那么也会调用GET API,而不会调用OPTIONS API。因此,OPTIONS API在我们第一次加载应用程序时被调用,但根据我的理解,在使用Spring Security时,OPTIONS API应该在任何其他API调用之前被调用。

HelloWorldController.java

@CrossOrigin(origins="http://localhost:4200")
@RestController
public class HelloWorldController {

    @GetMapping(path="/hello/path-variable/{name}")
    public HelloWorldBean helloVariable(@PathVariable String name) {
        return new HelloWorldBean(String.format("Hello message %s", name));
    }
}

SpringSecurityConfigurationBasicAuth.java

@Configuration
@EnableWebSecurity
public class SpringSecurityConfigurationBasicAuth extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
            .antMatchers(HttpMethod.OPTIONS,"/**").permitAll()
            .anyRequest().authenticated()
            .and()
            //.formLogin().and()
            .httpBasic();
    }
}

welcome-data.service.ts

import { Injectable } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';

export class HelloWorldBean {
    constructor(public message: string) {

    }
}

@Injectable({
    providedIn: 'root'
})
export class WelcomeDataService {

    constructor(private http: HttpClient) {

    }

    executeHelloWorldBeanServicePathVarible(name) {
        let basicAuthHeaderString = this.createBasicAuthenticationHttpHeader();

        let headers = new HttpHeaders({
            Authorization: basicAuthHeaderString
        });

        return this.http.get<HelloWorldBean>(`http://localhost:8080/hello/path-variable/${name}`, { headers });
    }

    createBasicAuthenticationHttpHeader() {
        let username = 'user';
        let password = 'dummy';

        let basicAuthHeaderString = 'Basic ' + window.btoa(username + ':' + password);
        return basicAuthHeaderString;
    }
}

Network logs

Request URL: http://localhost:8080/hello/path-variable/user
Request Method: GET
Status Code: 200 
Remote Address: [::1]:8080
Referrer Policy: no-referrer-when-downgrade

Response:

{"message":"Hello message user"}
英文:

OPTIONS API is getting called with 200 status code only once when I start the server first time and if I refresh the page again then only GET API is called or if I stop the server and then restart the server then also GET API is called and not OPTIONS API.So is OPTIONS API is called once we load the application first time but as per my understanding when we have spring security then OPTIONS API should be called first before any other API call

HelloWorldController.java

@CrossOrigin(origins=&quot;http://localhost:4200&quot;)
@RestController
public class HelloWorldController {

@GetMapping(path=&quot;/hello/path-variable/{name}&quot;)
public HelloWorldBean helloVariable(@PathVariable String name) {
	return  new HelloWorldBean(String.format(&quot;Hello message %s&quot;,name));
	}}

SpringSecurityConfigurationBasicAuth.java

@Configuration
@EnableWebSecurity
public class SpringSecurityConfigurationBasicAuth extends WebSecurityConfigurerAdapter{

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http
		.csrf().disable()
			.authorizeRequests()
			.antMatchers(HttpMethod.OPTIONS,&quot;/**&quot;).permitAll()
				.anyRequest().authenticated()
				.and()
			//.formLogin().and()
			.httpBasic();
	}
}

welcome-data.service.ts

import { Injectable } from &#39;@angular/core&#39;;
import { HttpClient, HttpHeaders } from &#39;@angular/common/http&#39;;

export class helloWorldBean{
  constructor( public message:string){

  }
}
@Injectable({
  providedIn: &#39;root&#39;
})

export class WelcomeDataService {

  constructor(private http:HttpClient) {
    
   }


  executeHelloWorldBeanServicePathVarible(name)
  {
    let basicAuthHeaderString=this.createBasicAuthenticationHttpHeader();

    let headers = new HttpHeaders({
Authorization: basicAuthHeaderString

    })
    return this.http.get&lt;helloWorldBean&gt;
    (`http://localhost:8080/hello/path-variable/${name}`, {headers});
  }

  createBasicAuthenticationHttpHeader(){
    let username=&#39;user&#39;
    let password=&#39;dummy&#39;

    let basicAuthHeaderString=&#39;Basic &#39; + window.btoa(username + &#39;:&#39; + password);
     return basicAuthHeaderString;
  } 
}

Network logs

Request URL: http://localhost:8080/hello/path-variable/user
Request Method: GET
Status Code: 200 
Remote Address: [::1]:8080
Referrer Policy: no-referrer-when-downgrade

Response:

{&quot;message&quot;:&quot;Hello message user&quot;}

答案1

得分: 1

预检请求或OPTIONS调用在浏览器中根据一定的持续时间进行缓存。它由Access-Control-Max-Age头属性控制。

第一次启动服务器并命中URL时,浏览器将调用OPTIONS方法调用以获取允许的方法等信息。但随后的请求将使用此缓存。

如果不想使用缓存,其值应设置为-1。

Access-Control-Max-Age: -1

有关此头参数的更多信息在这里 -

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age#:~:text=The%20Access%2DControl%2DMax%2D,Headers%20headers

我相信您可以简单地在CorsRequest注释中设置maxAge,就会为您设置Header参数,如下所示 -

@CrossOrigin(origins="http://localhost:4200", maxAge=-1)
@RestController
public class HelloWorldController {

这将禁用缓存,并且所有请求将调用预检请求。

英文:

The pre-flight request or the OPTIONS call is cached for certain duration depending upon the browser. It is controlled by Access-Control-Max-Age header property.

The first time you start the server and hit the url, browser will invoke OPTIONS method call to fetch the allowed methods etc. But it is then cached and the subsequent requests must be using this cache.

If you don't want to use the cache, it's value should be set to -1.

Access-Control-Max-Age: -1

More Information about this header parameter is here -

https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age#:~:text=The%20Access%2DControl%2DMax%2D,Headers%20headers

I believe you can simply set the maxAge in CorsRequest annotation and this will set the Header Parameter for you like this -

@CrossOrigin(origins=&quot;http://localhost:4200&quot;, maxAge=-1)
@RestController
public class HelloWorldController {

This should disable the cache and all requests will call the Preflight request.

huangapple
  • 本文由 发表于 2020年9月13日 22:21:39
  • 转载请务必保留本文链接:https://go.coder-hub.com/63871843.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定