工作中遇到的一个axios跨域请求问题,记录下最终的解决方法。
问题描述
前端用Vue,引入了axios,调用的是rails项目中的接口。vue 2.5.17 , rails 5.2.1
Vue项目中,配置文件含如下内容:
axios: {
// See https://github.com/nuxt-community/axios-module#options
baseURL:
process.env.NODE_ENV === 'production'
? 'https://xxxxxx/v2'
: 'http://api.xxxxx:3000/v2',
credentials: true
},
设置credentials为true,axios请求时,会自动携带cookie。本地运行 yarn run dev
,设置端口为4000.
浏览器打开localhost:4000
, 没有任何反应,查看chrome 开发者模式下的console,出现如下报错:
Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
解决方法
需要在rails项目中,安装gem rack-cors
gem 'rack-cors', :require => 'rack/cors'
bundle后,在config/application.rb
文件中,添加如下语句:
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*', headers: :any, methods: [:get, :post, :options]
end
end
重启rails项目。
这时,本地再次访问locahost:4000,如果console依然报错:
Access to XMLHttpRequest at 'http://api.xxxxx:3000/v2' from origin 'http://localhost:4000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
请修改rails项目的config/application.rb
文件,在resource中添加credentials: true
,同时设置origins,添加正则来限定请求访问的来源地址,如果只是单单添加credentials: true
,重启rails时,Rack::Cors会弹出报错:
Allowing credentials for wildcard origins is insecure. Please specify more restrictive origins or set 'credentials' to false in your CORS configuration. (Rack::Cors::Resource::CorsMisconfigurationError)
最终添加到config/application.rb
文件的配置内容如下:
config.middleware.insert_before 0, Rack::Cors do
allow do
origins %r{/A***your-regex***\z/}x
resource '*', headers: :any, methods: [:get, :post, :options], credentials: true
end
end
重启rails项目。
再次访问,OK。