Fw/1(Lucee) - Framework7 中的 CORS 策略导致 Ajax 请求失败

问题描述

为了在 FW/1 (4.2) (lucee 5.2.9) 中取回 json 数据,我在 Framework7 中收到了以下 ajax 请求,但不幸的是,由于通过 Chrome 浏览器的 CORS 策略,我收到了错误

app.request({
  url:"http://127.0.0.1:49820/index.cfm/user/login/",type:"POST",data:JSON.stringify({
    "username":username,"password":password
  }),crossDomain: true,xhrFields: { withCredentials: false },headers: {
   'Access-Control-Allow-Origin': '*','Access-Control-Allow-Methods':'GET,HEAD,OPTIONS,POST,PUT','Access-Control-Allow-Headers': 'Origin,X-Requested-With,Content-Type,Accept,Authorization','Content-type': 'text/javascript; charset=utf-8',},dataType:"jsonp",success:function(result){
      console.log(result);
  }

 });

在我的 Fw/1 application.cfc 中,我有以下设置:

variables.framework =   {
      preflightOptions = true,generateSES = true,routes= [
        { "$POST/user/login/" = "/main/get" }
        ] 
    };

在我的主控制器中获取操作,我通过

获取json
rc.user_info = variables.userService.login(rc.dsn,rc.username,rc.password);
variables.fw.renderData( "json",rc.user_info);

不幸的是我收到以下消息

从源“http://localhost”访问“http://127.0.0.1:49820/index.cfm/user/login/”的 XMLHttpRequest 已被 CORS 策略阻止:请求标头字段访问预检响应中的 Access-Control-Allow-Headers 不允许 -control-allow-origin

关于请求头信息,我收到以下信息,据我所知,参数也被传递了:

enter image description here

有什么可以帮助我的想法吗?

问候

解决方法

您使用的是哪个版本的 FW/1?我假设最新的?

我对 Framework7 的 ajax 功能的工作原理一无所知,但我会尝试在 preflightOptions = true 的 FW/1 框架设置中设置 Application.cfc(如果您还没有设置),看看这是否能解决您的问题问题。

查看 http://framework-one.github.io/documentation/4.3/developing-applications/#options-supportOPTIONS Support 部分

更新

由于使用了 preFlightOptions...

我的下一个建议是在 FW/1 的框架设置中设置您允许的标头。您可以通过定义 optionsAccessControl.headers = "your,headers,here" 来做到这一点。这在我已经分享的链接中都有提到。

如果您愿意,您可以将 optionsAccessControl 结构定义为一个整体并设置其他键。

optionsAccessControl = {
  origin: "",headers: "",credentials: true/false,maxAge: 12345
}

更新 2

同样的问题是 cross-posted to the FW/1 GitHub Repository,所以为了透明起见,我想在这里为可能遇到此问题的任何人分享解决方案...

Application.cfc 中,包括以下框架设置:

generateSES = true,SESOmitIndex = true,preflightOptions = true,optionsAccessControl = {
    origin: "*",headers: "Origin,X-Requested-With,Content-Type,Accept,Authorization,Access-Control-Allow-Headers,Access-Control-Allow-Methods,Access-Control-Allow-Origin"
}

在控制器方法中传递带有响应的原始标头:

variables.fw.renderData( "json",rc.user_info).header( "Access-Control-Allow-Origin","*" );

注意:出于安全原因,最佳做法是不允许使用“*”,而只允许调用/响应的域。 (示例:http://127.0.0.1:12345

,

CORS 的功能是阻止端点未明确允许的浏览器请求(这是请求的“来源”)。在您的情况下,端点位于 http://127.0.0.1:49820/index.cfm/user/login/。不可能通过纯客户端代码告诉客户端绕过它(就像您通过在 ajax 请求的请求标头中提交它们所做的那样)绕过它。这会破坏 CORS 功能并破坏 CORS 的设计目的。

实现 CORS 的正确方法是在 FW/1 框架的 index.cfm/user/login/ 端点处将它们作为服务器响应标头来实现,而不是在 AJAX 请求中。在 cfml 中,您通常通过使用 cfheader 标记设置服务器响应头来实现它们。以下是一些允许请求的典型示例。请验证 FW1 端点是否正在提交这些服务器 http 响应标头(例如,通过使用 chrome 开发工具检查响应)。

假设您使用 URL http://mydomain1:8080 打开浏览器应用,并且您的端点不同(域/IP/协议或端口),例如在 http://mydomain2:49820/index.cfm/user/login/,然后您需要将这些服务器响应标头添加到您提交 JSON 类似的端点代码中,如下所示:

<cfheader name="access-control-allow-origin" value="http://mydomain1:8080">
<cfheader name="access-control-allow-credentials" value="true">
<cfheader name="access-control-allow-headers" value="Content-Type">

有关详细信息,请参阅有关 CORS here

的文档