POST 对 OPTIONS 的更改 + 对预检请求的响应未通过访问控制检查:否 'Access-Control-Allow-Origin' header
POST changes to OPTIONS + Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header
XMLHttpRequest cannot load http://xxx.xxx. Response to preflight
request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'null' is therefore not allowed access. The response
had HTTP status code 500.
我正在尝试发送带有 ajax 的 xml soap,但出现了错误。我尝试了很多选项,但似乎没有任何效果,这是代码:
var soapMessage =
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://xxx.xxx/">'+
'<soapenv:Header/>'+
'<soapenv:Body>'+
'<wsdl:test1>'+
'<PUI>12345</PUI>'+
'</wsdl:test1>'+
' </soapenv:Body>'+
'</soapenv:Envelope>';
$.ajax({
url: 'http://xxx.xxx',
type: 'POST',
dataType: 'xml',
data: soapMessage,
crossDomain: true,
processData: false,
contentType: 'text/xml; charset=\"utf-8\"',
headers: {
SOAPAction: "http://xxx.xxx"
},
success: function (msg, data) {
alert(msg);
},
error: function (msg, data) {
alert("Error");
}
});
我在这里做错了什么?我发送了一个 POST 动作,但它把它读作选项。
如何解决这个问题?
我使用 Boomerang Rest 和 Soap Client 来测试这个服务,它给我正确的响应。当我使用我自己的程序时,它给我 XMLHttpRequest cannot load http://xxxxx" 错误。我正在使用 apache tomcat 6.0 并使用 Java 代码的 Web 应用程序
您正在执行该请求 cross-origin,因此您向其发出请求的服务器必须发送 Access-Control-Allow-Origin
响应 header 以表明它允许 cross-origin请求。
详情见https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS。
For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and Fetch follow the same-origin policy. So, a web application using XMLHttpRequest or Fetch could only make HTTP requests to its own domain.
而 OPTIONS
请求发生的原因是当您发送 cross-origin 请求时 Content-Type
header 的值不是 application/x-www-form-urlencoded
、multipart/form-data
或 text/plain
,您的浏览器首先执行 CORS preflight 检查。
您的请求发送 Content-Type: text/xml; charset="utf-8"
,因此会导致预检。
如果您向其发送请求的服务器不是您控制和配置的服务器,就解决方法而言,您可以使用开放式反向代理,例如 https://cors-anywhere.herokuapp.com/。
它的工作方式是,不是将您的请求直接发送到 http://xxx.xxx
,而是将它发送到 https://cors-anywhere.herokuapp.com/http://xxx.xxx,它会代理您的请求并以 Access-Control-Allow-Origin
和其他预期的方式响应CORS headers.
当然,您需要意识到,如果您的请求包含任何凭据,您就会将这些凭据暴露给 cors-anywhere.herokuapp.com
的维护者。
我的解决方法是编写一个过滤器,将原点作为可接受的原点附加到任何选项请求上,并将其添加到需要接受此类请求的任何 servlet 中。这是我的实现:
public class CorsFilter implements Filter {
private static List<String> validServers = Arrays.asList([you need to fill this in with whatever sites you want to allow access]);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
if (servletRequest instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String origin = request.getHeader("Origin");
if (StringUtils.isNotBlank(origin)) { //this is a cors request
boolean hasPrefix = origin.contains("/");
boolean hasPort = origin.contains(":");
String serverAlias = origin.substring(hasPrefix ? origin.lastIndexOf("/") + 1 : 0, hasPort ? origin.lastIndexOf(":") : origin.length());
if (validServers.contains(serverAlias)) {
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "OPTIONS, POST, GET, PUT, DELETE");
response.setHeader("Access-Control-Allow-Origin", origin);
response.setHeader("Access-Control-Allow-Headers", "Content-Type");
//credentials are not sent on options requests, kick out here so that the access control headers and nothing else can be returned
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(200);
return;
}
} else {
response.sendError(HttpStatus.SC_FORBIDDEN);
response.flushBuffer();
return;
}
}
}
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
XMLHttpRequest cannot load http://xxx.xxx. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 500.
我正在尝试发送带有 ajax 的 xml soap,但出现了错误。我尝试了很多选项,但似乎没有任何效果,这是代码:
var soapMessage =
'<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsdl="http://xxx.xxx/">'+
'<soapenv:Header/>'+
'<soapenv:Body>'+
'<wsdl:test1>'+
'<PUI>12345</PUI>'+
'</wsdl:test1>'+
' </soapenv:Body>'+
'</soapenv:Envelope>';
$.ajax({
url: 'http://xxx.xxx',
type: 'POST',
dataType: 'xml',
data: soapMessage,
crossDomain: true,
processData: false,
contentType: 'text/xml; charset=\"utf-8\"',
headers: {
SOAPAction: "http://xxx.xxx"
},
success: function (msg, data) {
alert(msg);
},
error: function (msg, data) {
alert("Error");
}
});
我在这里做错了什么?我发送了一个 POST 动作,但它把它读作选项。 如何解决这个问题?
我使用 Boomerang Rest 和 Soap Client 来测试这个服务,它给我正确的响应。当我使用我自己的程序时,它给我 XMLHttpRequest cannot load http://xxxxx" 错误。我正在使用 apache tomcat 6.0 并使用 Java 代码的 Web 应用程序
您正在执行该请求 cross-origin,因此您向其发出请求的服务器必须发送 Access-Control-Allow-Origin
响应 header 以表明它允许 cross-origin请求。
详情见https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS。
For security reasons, browsers restrict cross-origin HTTP requests initiated from within scripts. For example, XMLHttpRequest and Fetch follow the same-origin policy. So, a web application using XMLHttpRequest or Fetch could only make HTTP requests to its own domain.
而 OPTIONS
请求发生的原因是当您发送 cross-origin 请求时 Content-Type
header 的值不是 application/x-www-form-urlencoded
、multipart/form-data
或 text/plain
,您的浏览器首先执行 CORS preflight 检查。
您的请求发送 Content-Type: text/xml; charset="utf-8"
,因此会导致预检。
如果您向其发送请求的服务器不是您控制和配置的服务器,就解决方法而言,您可以使用开放式反向代理,例如 https://cors-anywhere.herokuapp.com/。
它的工作方式是,不是将您的请求直接发送到 http://xxx.xxx
,而是将它发送到 https://cors-anywhere.herokuapp.com/http://xxx.xxx,它会代理您的请求并以 Access-Control-Allow-Origin
和其他预期的方式响应CORS headers.
当然,您需要意识到,如果您的请求包含任何凭据,您就会将这些凭据暴露给 cors-anywhere.herokuapp.com
的维护者。
我的解决方法是编写一个过滤器,将原点作为可接受的原点附加到任何选项请求上,并将其添加到需要接受此类请求的任何 servlet 中。这是我的实现:
public class CorsFilter implements Filter {
private static List<String> validServers = Arrays.asList([you need to fill this in with whatever sites you want to allow access]);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
if (servletRequest instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
String origin = request.getHeader("Origin");
if (StringUtils.isNotBlank(origin)) { //this is a cors request
boolean hasPrefix = origin.contains("/");
boolean hasPort = origin.contains(":");
String serverAlias = origin.substring(hasPrefix ? origin.lastIndexOf("/") + 1 : 0, hasPort ? origin.lastIndexOf(":") : origin.length());
if (validServers.contains(serverAlias)) {
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "OPTIONS, POST, GET, PUT, DELETE");
response.setHeader("Access-Control-Allow-Origin", origin);
response.setHeader("Access-Control-Allow-Headers", "Content-Type");
//credentials are not sent on options requests, kick out here so that the access control headers and nothing else can be returned
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(200);
return;
}
} else {
response.sendError(HttpStatus.SC_FORBIDDEN);
response.flushBuffer();
return;
}
}
}
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}