Javascript 否';访问控制允许原点';请求的资源上存在标头—;尝试从REST API获取数据时
我正在尝试从HP Alm的REST API获取一些数据。它与一个小的curl脚本配合得很好——我得到了我的数据 现在,使用JavaScript、fetch和ES6(或多或少)这样做似乎是一个更大的问题。我一直收到以下错误消息: 无法加载获取API。对飞行前请求的响应不正确 通过访问控制检查:未显示“访问控制允许原点”标题 在请求的资源上显示。来源“”是 因此不允许访问。响应的HTTP状态代码为501。 如果不透明响应满足您的需要,请将请求的模式设置为 “无cors”以获取禁用cors的资源 我理解这是因为我试图从本地主机中获取数据,解决方案应该使用CORS。现在我想我真的做到了,但不知怎么的,它要么忽略了我在标题中写的内容,要么问题出在其他地方 那么,是否存在实施问题?我做错了吗?很遗憾,我无法检查服务器日志。我真的有点困在这里了Javascript 否';访问控制允许原点';请求的资源上存在标头—;尝试从REST API获取数据时,javascript,cors,fetch-api,preflight,Javascript,Cors,Fetch Api,Preflight,我正在尝试从HP Alm的REST API获取一些数据。它与一个小的curl脚本配合得很好——我得到了我的数据 现在,使用JavaScript、fetch和ES6(或多或少)这样做似乎是一个更大的问题。我一直收到以下错误消息: 无法加载获取API。对飞行前请求的响应不正确 通过访问控制检查:未显示“访问控制允许原点”标题 在请求的资源上显示。来源“”是 因此不允许访问。响应的HTTP状态代码为501。 如果不透明响应满足您的需要,请将请求的模式设置为 “无cors”以获取禁用cors的资源 我理
function performSignIn() {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
headers.append('GET', 'POST', 'OPTIONS');
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
fetch(sign_in, {
//mode: 'no-cors',
credentials: 'include',
method: 'POST',
headers: headers
})
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log('Authorization failed : ' + error.message));
}
我用的是铬。我也尝试过使用Chrome CORS插件,但随后我收到另一条错误消息:
响应中“Access Control Allow Origin”标头的值
当请求的凭据模式为时,不能为通配符“*”
“包括”。因此,不允许使用源“”
通道由发起的请求的凭据模式
XMLHttpRequest由withCredentials属性控制
这个答案涵盖了很多方面,因此分为三个部分:
- 如何使用CORS代理解决“无访问控制允许源站标头”问题
- 如何避免CORS飞行前
- 如何解决“访问控制允许源标题不能是通配符”的问题
如何使用CORS代理来避免“无访问控制允许源站标头”问题 如果您不控制前端代码向其发送请求的服务器,而该服务器的响应问题只是缺少必要的
Access control Allow Origin
头,那么您仍然可以通过CORS代理发出请求来完成工作
您可以使用中的代码轻松运行自己的代理。您还可以使用5个命令,在2-3分钟内轻松地将自己的代理部署到Heroku:
git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku master
在运行这些命令之后,您将在运行自己的CORS Anywhere服务器,例如,https://cryptic-headland-94862.herokuapp.com/
现在,将代理的URL作为请求URL的前缀:
https://cryptic-headland-94862.herokuapp.com/https://example.com
添加代理URL作为前缀会导致通过代理发出请求,然后:
https://example.com
https://example.com
访问控制允许原点
标题添加到响应中访问控制允许原点的响应是浏览器看到的
即使请求触发浏览器执行CORS飞行前选项
请求,这也会起作用,因为在这种情况下,代理还会发回飞行前成功所需的访问控制允许标头
和访问控制允许方法
标头
如何避免CORS飞行前检查
问题中的代码会触发CORS预飞行,因为它会发送授权
标题
即使没有它,Content-Type:application/json
头也会触发预飞行
“飞行前”的意思是:在浏览器尝试问题代码中的POST
之前,它将首先向服务器发送一个OPTIONS
请求,以确定服务器是否选择接收具有Authorization
和内容类型:application/json
标题的跨源POST
它与一个小的curl脚本配合得很好——我得到了我的数据
要使用curl
进行正确测试,必须模拟浏览器发送的飞行前选项
请求:
curl -i -X OPTIONS -H "Origin: http://127.0.0.1:3000" \
-H 'Access-Control-Request-Method: POST' \
-H 'Access-Control-Request-Headers: Content-Type, Authorization' \
"https://the.sign_in.url"
…带有https://the.sign_in.url
替换为您实际登录的URL
浏览器需要从该选项请求中看到的响应必须具有如下标题:
import express from 'express';
const emailRouter = require('./routes/email'); // in my case, I was sending an email through a form in ReactJS
const fs = require('fs');
const https = require('https');
const app = express();
const port = 8000;
// CORS (Cross-Origin Resource Sharing) headers to support Cross-site HTTP requests
app.all('*', (req, res, next) => {
res.header("Access-Control-Allow-Origin", "https://localhost:3000");
next();
});
// Routes definition
app.use('/email', emailRouter);
// HTTPS server
const credentials = {
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server.crt')
};
const httpsServer = https.createServer(credentials, app);
httpsServer.listen(port, () => {
console.log(`Back-end running on port ${port}`);
});
访问控制允许原点:http://127.0.0.1:3000
访问控制允许方法:POST
访问控制允许标头:内容类型、授权
如果选项
响应不包含这些标题,那么浏览器将立即停止,甚至不会尝试发送POST
请求。此外,响应的HTTP状态代码必须是2xx,通常为200或204。如果是任何其他状态代码,浏览器将立即停止
问题中的服务器使用501状态代码响应选项
请求,这显然意味着它试图表明它没有实现对选项
请求的支持。在这种情况下,其他服务器通常使用405“不允许使用方法”状态代码进行响应
因此,如果服务器以405或501或200或204以外的任何方式响应该选项
请求,或者如果服务器没有以这些必要的响应头响应,则您永远无法从前端JavaScript代码直接向该服务器发出POST
请求
避免触发问题案例飞行前准备的方法是:
- 如果服务器不需要
授权
var cors = require('cors')
app.use(cors()) // Use this after the variable declaration
credentials: 'include',
async function get_ajax_data(){
var _reprojected_lat_lng = await $.ajax({
type: 'GET',
dataType: 'jsonp',
data: {},
url: _reprojection_url,
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR)
},
success: function (data) {
console.log(data);
// note: data is already json type, you
// just specify dataType: jsonp
return data;
}
});
} // function
@Value( "${app.allow.origins}" )
private String allowOrigins;
@Bean
public WebMvcConfigurer corsConfigurer() {
System.out.println("allow origin: "+allowOrigins);
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
//.allowedOrigins("http://localhost")
.allowedOrigins(allowOrigins)
.allowedMethods("PUT", "DELETE","GET", "POST");
}
};
}
headers.append('Access-Control-Allow-Origin', 'http://localhost:3000');
headers.append('Access-Control-Allow-Credentials', 'true');
headers.append('GET', 'POST', 'OPTIONS');
Access-Control-Allow-Origin : http://localhost:3000
Access-Control-Allow-Credentials : true
Access-Control-Allow-Methods : GET, POST, OPTIONS
Access-Control-Allow-Headers : Origin, Content-Type, Accept
function performSignIn() {
let headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
headers.append('Authorization', 'Basic ' + base64.encode(username + ":" + password));
headers.append('Origin','http://localhost:3000');
fetch(sign_in, {
mode: 'cors',
credentials: 'include',
method: 'POST',
headers: headers
})
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log('Authorization failed : ' + error.message));
}
$URL = $_GET['url'];
echo json_encode(file_get_contents($URL));
die();
fetch('https://example.com/no-cors.php' + '?url=' + url)
.then(response=>{*/Handle Response/*})`
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_METHOD} ^OPTIONS
RewriteRule .* . [F]
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine off
RewriteCond %{REQUEST_METHOD} ^OPTIONS
RewriteRule .* . [F]
</IfModule>
post(
this.serverUrl, dataObjToPost,
{
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
}
)
header("Access-Control-Allow-Origin: http://localhost:4200");
header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
header("Access-Control-Allow-Headers: Content-Type, Authorization");
$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
print_r($request);
server.key & server.crt
import express from 'express';
const emailRouter = require('./routes/email'); // in my case, I was sending an email through a form in ReactJS
const fs = require('fs');
const https = require('https');
const app = express();
const port = 8000;
// CORS (Cross-Origin Resource Sharing) headers to support Cross-site HTTP requests
app.all('*', (req, res, next) => {
res.header("Access-Control-Allow-Origin", "https://localhost:3000");
next();
});
// Routes definition
app.use('/email', emailRouter);
// HTTPS server
const credentials = {
key: fs.readFileSync('server.key'),
cert: fs.readFileSync('server.crt')
};
const httpsServer = https.createServer(credentials, app);
httpsServer.listen(port, () => {
console.log(`Back-end running on port ${port}`);
});
https.createServer(credentials, (req: any, res: any) => {
res.writeHead(200);
res.end("hello world from SSL\n");
}).listen(port, () => {
console.log(`HTTPS server listening on port ${port}...`);
});
await axios.get(`https://localhost:8000/email/send`, {
params: {/* whatever data you want to send */ },
headers: {
'Content-Type': 'application/json',
}
})
HTTPS=true SSL_CRT_FILE=server.crt SSL_KEY_FILE=server.key npm start
const cors = require('cors');
const userRouter = require('./routers/user');
expressApp = express();
expressApp.use(cors());
expressApp.use(express.json());
expressApp.use(userRouter);
fetch(sign_in, {
mode: 'no-cors',
credentials: 'include',
method: 'POST',
headers: headers
})
.then(response => response.json())
.then(json => console.log(json))
.catch(error => console.log('Authorization failed : ' + error.message));
}
app.use((req, res, next) =>{
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Headers','Origin, X-Requested-With, Content-Type,Accept, Authortization');
res.setHeader('Acces-Control-Allow-Methods','GET, POST, PATCH, DELETE');
`[[redirects]]
from = "/cors-proxy/*"
to = ":splat"
status = 200
force = true`
services.AddCors();
app.UseCors(options =>
options.WithOrigins("http://localhost:8080")
.AllowAnyHeader()
.AllowAnyMethod());
make sure you add this before - app.UseRouting();
npm install cors
const cors = require('cors');
app.use(cors());