Javascript 节点开发服务器和Spring引导应用程序之间的跨源请求被阻止

Javascript 节点开发服务器和Spring引导应用程序之间的跨源请求被阻止,javascript,java,node.js,spring,cross-domain,Javascript,Java,Node.js,Spring,Cross Domain,我的堆栈如下所示: 后端:Spring引导(Java)在:8088公开 前端:Vue托管在节点开发服务器上,暴露于:8080 在前端,我正在http common.js中重新配置axios,以将baseURL放入Spring boot应用程序,并允许从节点开发服务器进行连接: import axios from 'axios' export const AXIOS = axios.create({ baseURL: `http://localhost:8088`, headers: {

我的堆栈如下所示:

后端:Spring引导(Java)在:8088公开

前端:Vue托管在节点开发服务器上,暴露于:8080

在前端,我正在
http common.js
中重新配置
axios
,以将baseURL放入Spring boot应用程序,并允许从节点开发服务器进行连接:

import axios from 'axios'

export const AXIOS = axios.create({
  baseURL: `http://localhost:8088`,
  headers: {
    'Access-Control-Allow-Origin': 'http://localhost:8080'
  }
})
但是,当尝试发出
post
登录请求时,我将在控制台中收到以下消息:

跨源请求被阻止:同一源策略不允许读取远程资源http://localhost:8088/api/login. (原因:CORS飞行前频道未成功)。

这让我想到:spring启动应用程序有问题吗

但是没有,在main方法中,我在从运行于8080的节点应用程序到达
/api/*
端点时全局启用了CORS:

@Bean
public WebMvcConfigurer corsConfigurer() { // Enables CORS globally
    return new WebMvcConfigurerAdapter() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/api/*").allowedOrigins("http://localhost:8080");
        }
    };
} 
在我看来,它似乎应该正确配置。然而,到目前为止,下面的username+password帖子根本没有到达后端Spring引导应用程序。问题必须与节点应用程序有关

这是前端中的登录方法:

login ({commit}, authData) {
      AXIOS.post('/api/login', {
        username: authData.username,
        password: authData.password,
        withCredentials: true
      })
        .then(res => {
          console.log(res)
          commit('authUser', {
            token: res.data.idToken,
            userId: res.data.localId
          })
        })
        .catch(error => console.log(error))
    }
为了进一步巩固我的观点,我可以转到spring启动应用程序并获得正确的响应(一个有效的JWT!):

请求:

curl -i -H "Content-Type: application/json" -X POST -d '{
        "username": "sysadmin",
        "password": "sysadmin"
        }' http://localhost:8088/api/login
答复:

HTTP/1.1 200
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
X-Application-Context: application:8088
authentication: <very long JWT string>
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
结果与之前完全相同


将“Access Control Allow Origin”头添加到ajax post调用中是无用的,因为它是cors规范的一部分,必须由服务器设置为http响应的一部分

export const AXIOS = axios.create({
  baseURL: `http://localhost:8088`,
  headers: {
    //you can remove this header
    'Access-Control-Allow-Origin': 'http://localhost:8080'
  }
})
您可以卷曲应用程序,因为cors异常是由浏览器不允许您访问有效负载引起的。浏览器在任何跨域调用之前执行飞行前(选项)请求,在实际http请求之前确保您有权查看有效负载,您只需在“网络”选项卡下的控制台中查看即可

问题很可能是服务器端,不知何故您没有正确配置http响应的cors头

export const AXIOS = axios.create({
  baseURL: `http://localhost:8088`,
  headers: {
    //you can remove this header
    'Access-Control-Allow-Origin': 'http://localhost:8080'
  }
})
确保您不仅设置了Access Control Allow Origin标头(必须包含特定域,而不是*,因为您处于凭据模式),而且还设置了Access Control Allow credential,因为您正在发送凭据,以及Access Control Allow方法(必须至少包含推送和选项方法)

在chrome开发工具控制台的“网络”选项卡下,如果您检查ajax调用,您可以看到http响应的标题,应该是这样的


将“Access Control Allow Origin”头添加到ajax post调用中是无用的,因为它是cors规范的一部分,必须由服务器设置为http响应的一部分

export const AXIOS = axios.create({
  baseURL: `http://localhost:8088`,
  headers: {
    //you can remove this header
    'Access-Control-Allow-Origin': 'http://localhost:8080'
  }
})
您可以卷曲应用程序,因为cors异常是由浏览器不允许您访问有效负载引起的。浏览器在任何跨域调用之前执行飞行前(选项)请求,在实际http请求之前确保您有权查看有效负载,您只需在“网络”选项卡下的控制台中查看即可

问题很可能是服务器端,不知何故您没有正确配置http响应的cors头

export const AXIOS = axios.create({
  baseURL: `http://localhost:8088`,
  headers: {
    //you can remove this header
    'Access-Control-Allow-Origin': 'http://localhost:8080'
  }
})
确保您不仅设置了Access Control Allow Origin标头(必须包含特定域,而不是*,因为您处于凭据模式),而且还设置了Access Control Allow credential,因为您正在发送凭据,以及Access Control Allow方法(必须至少包含推送和选项方法)

在chrome开发工具控制台的“网络”选项卡下,如果您检查ajax调用,您可以看到http响应的标题,应该是这样的


您是否尝试将@CrossOrigin添加到您的登录REST方法中

@CrossOrigin(origins = "http://localhost:8080")
@GetMapping("/greeting")
public Greeting greeting(@RequestParam(required=false, defaultValue="World") String name) {
    System.out.println("==== in greeting ====");
    return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
更新:我刚刚在javadoc上读到这篇文章:

支持精确的路径映射URI(如“/admin”)以及Ant样式的路径模式(如“/admin/**”)


我在这里看不到带一颗星的路径,但您的路径是正确的Ant样式的路径。

您是否尝试将@CrossOrigin添加到您的登录REST方法中

@CrossOrigin(origins = "http://localhost:8080")
@GetMapping("/greeting")
public Greeting greeting(@RequestParam(required=false, defaultValue="World") String name) {
    System.out.println("==== in greeting ====");
    return new Greeting(counter.incrementAndGet(), String.format(template, name));
}
更新:我刚刚在javadoc上读到这篇文章:

支持精确的路径映射URI(如“/admin”)以及Ant样式的路径模式(如“/admin/**”)


我在这里没有看到一个带一颗星的路径,但是您的路径是一个正确的Ant样式的路径。

据我所知,如果它已经在main方法中配置为bean,那么这是不必要的(应该全局启用它)。但我会试试的。虽然,它根本没有到达服务器,而且响应是空的,所以我认为问题不在java方面?我尝试了你的方法,结果是一样的,因为我怀疑POST甚至从未到达REST端点,所以这肯定是node/express dev服务器的问题。你在registry.addMapping()方法中添加了断点吗?只是为了确保这个方法被命中。顺便说一下,我犯了一个错误,它是@CrossOrigin(origins=“)而不是@CrossOrigin(origins=“)是的,我发现了。登记处应该在哪里?你怎么做到的没问题。顺便问一下,您可以尝试使用/api/**或/api/login而不是/api/*。但我不确定这是否会改变什么,但这是我在一些教程中发现的。据我所知,如果它已经在主方法中配置为bean(应该全局启用),那么这是不必要的。但我会试试的。虽然,它根本没有到达服务器,而且响应是空的,所以我认为问题不在java方面?我尝试了你的方法,结果是一样的,因为我怀疑POST甚至从未到达REST端点,所以这肯定是node/express dev服务器的问题。你在registry.addMapping()方法中添加了断点吗?只是为了确保这个方法被命中。顺便说一下,我犯了一个错误@