无服务器和 PUT 命令的 CORS 问题

Posted

技术标签:

【中文标题】无服务器和 PUT 命令的 CORS 问题【英文标题】:CORS issue with Serverless and PUT command 【发布时间】:2017-08-13 18:47:49 【问题描述】:

我在使用 Serverless 和 AWS 时遇到了另一个 CORS 问题。似乎我需要专门告诉它以允许 PUT 方法,但我不确定这段代码的去向。我的 Lambda 函数有以下代码:

module.exports.update = (event, context, callback) => 
  const timestamp = new Date().getTime();
  const data = JSON.parse(event.body);
  if (typeof event.pathParameters.timeoffgroupid !== 'string') 
    console.error('Validation Failed');
    callback(new Error('Couldn\'t update the todo item.'));
    return;
  
  const params = 
    TableName: 'TimeOffGroup',
    Key: 
      timeoffgroupid: event.pathParameters.timeoffgroupid,
    ,
    ExpressionAttributeValues: 
      ':timeOffGroup': data.timeOffGroup,
      ':timeOffGroupColor': data.timeOffGroupColor,
      ':dateModified': timestamp
    ,
    UpdateExpression: 'SET timeOffGroup = :timeOffGroup, timeOffGroupColor = :timeOffGroupColor, dateModified = :dateModified',
    ReturnValues: 'ALL_NEW',
  ;

  dynamoDb.update(params, (error, result) => 
    if (error) 
      console.error(error);
      callback(new Error('Couldn\'t update the todo item.'));
      return;
    
    const response = 
      statusCode: 200,
      body: JSON.stringify(result.Attributes),
      headers: 
        "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
        "Access-Control-Allow-Credentials" : true
      
    ;
    callback(null, response);
  );
;

我得到的错误是:

XMLHttpRequest 无法加载 https://pwqlomgq89.execute-api.us-east-1.amazonaws.com/dev/timeoffgroup/7d463800-0935-11e7-b618-4b1d72ddca8e?timeOffGroup=Holiday+edited。 请求中不存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“http://localhost:9000” 使用权。响应的 HTTP 状态代码为 502。 angular.js:14328 可能未处理的拒绝: "data":null,"status":-1,"config":"method":"PUT","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback" ,"data":,"url":"https://pwqlomgq89.execute-api.us-east-1.amazonaws.com/dev/timeoffgroup/7d463800-0935-11e7-b618-4b1d72ddca8e","params":"timeOffGroup":"假日 已编辑","headers":"Accept":"application/json, text/plain, /","Content-Type":"application/json;charset=utf-8","statusText":""

我已关注无服务器教程中的所有调用,以使 CORS 正常工作。但似乎我得到了 get 和 create 工作,但 PUT 命令不起作用。是否有一些地方我仍然需要设置更新命令以允许跨域 PUT?

看起来我可能需要更多的 PUT 方法访问: 标题:


    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
    "Access-Control-Allow-Credentials" : true

【问题讨论】:

您收到该特定错误消息的原因可能只是您的服务器未配置为将 Access-Control-Allow-Origin 响应标头添加到服务器错误响应中。该消息表明的真正潜在问题是服务器端存在 502 错误,这似乎表明正在发生与您的 CORS 配置无关的其他故障。因此,您可能希望查看服务器日志以获取有关导致 502 服务器故障的原因的更多详细信息,以便您可以修复它。可能是一些简单的语法错误 是的,我查看了服务器日志,上面写着“ValidationException: Invalid UpdateExpression: An expression attribute value used in expression is not defined; attribute value: :timeOffGroupColor” 正在寻找拼写错误。跨度> 我在 javascript 中有一个未定义的值被传递到函数中。我现在可以解决这个问题了,谢谢大家的帮助。 【参考方案1】:

看来您的问题是您没有处理 OPTIONS 动词。请参阅此answer 以了解有关此要求的更多信息。

在发出PUT 请求之前,浏览器将预检OPTIONS 请求作为安全措施,以确保服务器预期这种请求。如果您不支持OPTIONS,则不会发出PUT 请求。

要解决此问题,请更改您的 serverless.yml 文件以添加 OPTIONS 支持。

functions:
  func:
    handler: handler.func
    events:
      - http: PUT foo/bar
      - http: OPTIONS foo/bar

用这样的方式修改你的句柄:

module.exports.func = (event, context, callback) => 

  try 
    switch(event.httpMethod + ' ' + event.resource) 
      case 'PUT /foo/bar':
        handlePut(callback);
        break;
      case 'OPTIONS /foo/bar':
        handleOptions(callback);
        break;
      default:
        // return HTTP 400
    
  
  catch (err) 
     // return HTTP 500
  
;

const handlePut = (callback) => 
    callback(null,  
        statusCode: 200, 
        headers: 
            'Access-Control-Allow-Origin': '*'
        , 
        body: JSON.stringify(
            message: 'PUT'
        )
    );
;

const handleOptions = (callback) => 
    callback(null, 
        statusCode: 200,
        headers: 
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Headers': 'origin, content-type, accept',
            'Access-Control-Allow-Methods': 'POST, PUT, OPTIONS'
        
    );
;

【讨论】:

【参考方案2】:

您可以尝试增加 lambda 中的超时时间。这解决了我的 CORS 问题。

【讨论】:

以上是关于无服务器和 PUT 命令的 CORS 问题的主要内容,如果未能解决你的问题,请参考以下文章

响应标头中的 Azure 无服务器功能启用 CORS

IIS 7.5 + 为 RESTFul 服务启用 PUT 和 DELETE,无扩展

如何在无服务器中允许 CORS 用于自定义标头?

无服务器框架 AWS REST API Gateway - 403 CORS 错误

无服务器 aws httpApi cors 设置

通过 API 网关为无服务器架构模型代理端点设置 CORS