字符串请求有效负载的ActionDispatch :: ParamsParser :: ParseError

时间:2016-04-08 11:01:05

标签: ruby-on-rails ruby json scorm tin-can-api

我收到来自API的标准请求。它看起来像这样:

enter image description here

它的内容类型和长度是:

enter image description here

但是当这次点击我的Rails服务器时,Rails会以

响应

enter image description here

我提出这个问题的原因是因为同样的请求似乎适用于SCORM Cloud的服务器。如果我向他们上传完全相同的内容,并在调试器中观看,我看到它发出一个application/json语句,其中包含相同的请求有效负载,但没有unexpected token错误。

Rails application/json请求是否必须以某种与其他服务器不同的方式编写?是否有正确的方法在Rack Middleware中重写此行以防止此错误?

更新

javascript:

function _TCDriver_XHR_request (lrs, url, method, data, callback, ignore404, extraHeaders) {
_TCDriver_Log("_TCDriver_XHR_request: " + url);
var xhr,
    finished = false,
    xDomainRequest = false,
    ieXDomain = false,
    ieModeRequest,
    title,
    ticks = ['/', '-', '\\', '|'],
    location = window.location,
    urlParts,
    urlPort,
    result,
    extended,
    until,
    fullUrl = lrs.endpoint + url
;

urlParts = fullUrl.toLowerCase().match(/^(.+):\/\/([^:\/]*):?(\d+)?(\/.*)?$/);

// add extended LMS-specified values to the URL
if (lrs.extended !== undefined) {
    extended = [];
    for (var prop in lrs.extended) {
        if(lrs.extended[prop] != null && lrs.extended[prop].length > 0){
            extended.push(prop + "=" + encodeURIComponent(lrs.extended[prop]));
        }
    }
    if (extended.length > 0) {
        fullUrl += (fullUrl.indexOf("?") > -1 ? "&" : "?") + extended.join("&");
    }
}

//Consolidate headers
var headers = {};
headers["Content-Type"] = "application/json";
headers["Authorization"] = lrs.auth;
if (extraHeaders !== null) {
    for (var headerName in extraHeaders) {
        headers[headerName] = extraHeaders[headerName];
    }
}

//See if this really is a cross domain
xDomainRequest = (location.protocol.toLowerCase() !== urlParts[1] || location.hostname.toLowerCase() !== urlParts[2]);
if (! xDomainRequest) {
    urlPort = (urlParts[3] === null ? ( urlParts[1] === 'http' ? '80' : '443') : urlParts[3]);
    xDomainRequest = (urlPort === location.port);
}

//If it's not cross domain or we're not using IE, use the usual XmlHttpRequest
if (! xDomainRequest || typeof XDomainRequest === 'undefined') {
    _TCDriver_Log("_TCDriver_XHR_request using XMLHttpRequest");
    xhr = new XMLHttpRequest();
    xhr.open(method, fullUrl, callback != null);
    for (var headerName in headers) {
        xhr.setRequestHeader(headerName, headers[headerName]);
    }
}
//Otherwise, use IE's XDomainRequest object
else {
    _TCDriver_Log("_TCDriver_XHR_request using XDomainRequest");
    ieXDomain = true;
    ieModeRequest = _TCDriver_GetIEModeRequest(method, fullUrl, headers, data);
    xhr = new XDomainRequest ();
    xhr.open(ieModeRequest.method, ieModeRequest.url);
}

2 个答案:

答案 0 :(得分:2)

Rails正在帮助"这里并假设客户正确使用" Content-Type"并传递实际匹配该内容类型的值。换句话说,请求中的有效负载必须是可解析的JSON,并且传递的值不是有效的JSON。

当您实施的内部API并非旨在实现最大的互操作性时,这是完全合理的。 Rails不知道的是LRS'文件存储应该是“愚蠢的”#34;并且基本上允许客户端推送它想要的任何内容并获得它想要的任何内容,这就是SCORM Cloud接受请求的原因,基本上它只是存储内容类型和内容,然后根据请求反刍它们。

您粘贴的代码来自非常旧库,其内容类型标头的实现很差。如果在其中任何一个主要电子学习创作工具的相对旧版本的内容中找到此代码,则应更新该代码以使用最新版本的TinCanJS并改进内容类型处理

至于在Rails上进行这项工作,对不起,我没有那么多经验。据推测,有一个开关或某些东西可以关闭自动请求体解析,至少是我使用的大多数其他框架都有的。

答案 1 :(得分:-1)

  

Rails application / json请求是否必须以某种与其他服务器不同的方式编写?

不是我知道没有。

  

是否有正确的方法在Rack Middleware中重写此行以防止此错误?

可能有一种方法是肯定的,甚至可能没有机架中间件,但如果没有实际的使用请求,很难帮助你。