1

API から標準リクエストを受け取りました。次のようになります。

ここに画像の説明を入力

コンテンツ タイプと長さは次のとおりです。

ここに画像の説明を入力

しかし、これが Rails サーバーに到達すると、Rails は次のように応答します。

ここに画像の説明を入力

これを取り上げる理由は、SCORM クラウドのサーバーでも同じリクエストが機能するようだからです。まったく同じコンテンツをアップロードしてデバッガで見るapplication/jsonと、同じ Request ペイロードを持つステートメントを送信していることがわかりますが、unexpected tokenエラーはありません。

Railsapplication/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);
}
4

2 に答える 2

2

Rails はここで「役に立ち」、クライアントが「Content-Type」を正しく使用し、実際にそのコンテンツ タイプに一致する値を渡していると想定しています。つまり、リクエストのペイロードは解析可能な JSON である必要があり、渡される値は有効な JSON ではありません。

最大限の相互運用性を意図していない社内 API を実装している場合、これは完全に合理的なことです。Rails が知らないのは、LRS のドキュメント ストレージは「ダム」であり、基本的にクライアントが必要なものを押し込んで、必要なものを取得できるようにすることです。これが、SCORM クラウドが要求を受け入れる理由です。コンテンツ タイプとコンテンツを格納し、要求に応じてそれらをそのまま逆流させます。

貼り付けたコードは、Content-Type ヘッダーの実装が不十分な非常に古いライブラリからのものです。このコードが、主要な e ラーニング オーサリング ツールの 1 つのコンテンツの比較的古いバージョン以外の場所で見つかった場合は、TinCanJSの最新バージョンを使用するように更新し、コンテンツ タイプの処理を改善する必要があります。

これを Rails で動作させる限り、申し訳ありませんが、あまり経験がありません。おそらく、リクエスト本文の自動解析をオフにするスイッチまたは何かがあると思われます。少なくとも、私が使用した他のほとんどのフレームワークにはそれがあります。

于 2016-04-08T13:40:13.813 に答える