0

I am working the TinCan API which is sending non-json objects as a JSON request.

An example of the Request Payload in said request :

AWSAccessKeyId=secret
&Authorization=secret
&activityId=61XkSYC1ht2%5Fcourse%5Fid
&Expires=1395864543
&Content%2DType=application%2Fjson
&actor=null
&registration=760e3480%2Dba55%2D4991%2D94b0%2D01820dbd23a2
&stateId=resume
&Signature=ZNYa7WTtO5rWx%2FAs%2FuFxTQkiYdc%3D

Their documentation explains in a paraphrased form that "The data is being sent as described in section 7.8 Cross Origin Requests of the XAPI spec, where all headers and content are being included as form parameters."

Which you can see is true from the Content key in the example above. That key and its children can be decoded and be parsed as JSON.

But because the initial request is application/json, my app runs into a JSON parse error.

That being said, is there some way to set up the server, or my controllers to accept these CORS requests so that I can properly parse them and use their information?

4

1 回答 1

1

If you're up against the wall and have no way of changing the completely broken client, you might want to try and gracefully recover here.

Usually you can add a filter in your config.ru file for your application that will re-write the damaged headers:

use TinCanFixer

Then you write a Rack handler:

class TinCanFixer
  def initialize(app)
    @app = app
  end

  def call(env)
    case (env["CONTENT_TYPE"])
    when "application/json"
      # Check that it's actually JSON
      unless (env["rack.input"].match(/^\{\[/))
        env["CONTENT_TYPE"] = "application/x-www-form-urlencoded"
      end
    end

    @app.call(env)
  end
end

Untested but should, in principle, sniff out non-JSON content and reassign the rack.input header which dictates content type.

于 2014-03-26T19:52:27.630 回答