Backbone: CORS рд╕рд┐рдВрдХ POST рдХреЗ рдмрдЬрд╛рдп OPTIONS рдЕрдиреБрд░реЛрдз рднреЗрдЬрддрд╛ рд╣реИ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 17 рдордИ 2013  ┬╖  17рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: jashkenas/backbone

I'm trying to use the model.save() with a rest service on another subdomain. рдореИрдВ рдХрд┐рд╕реА рдЕрдиреНрдп рд╕рдмрдбреЛрдореЗрди рдкрд░ рдЖрд░рд╛рдо рд╕реЗрд╡рд╛ рдХреЗ рд╕рд╛рде model.save() рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред I got the following request headers which are far from my expectations: рдореБрдЭреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЕрдиреБрд░реЛрдз рд╢реАрд░реНрд╖рд▓реЗрдЦ рдорд┐рд▓реЗ рдЬреЛ рдореЗрд░реА рдЕрдкреЗрдХреНрд╖рд╛рдУрдВ рд╕реЗ рдмрд╣реБрдд рджреВрд░ рд╣реИрдВ:

OPTIONS /user HTTP/1.1
Host: not.public
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:20.0) Gecko/20100101 Firefox/20.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Origin: http://not.public
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache

How to fix this? рдЗрд╕реЗ рдХреИрд╕реЗ рдареАрдХ рдХрд░реЗрдВ?

Ofc. рдУрдПрдлрд╕реА my REST server responds 404 not found for an OPTIONS call... рдореЗрд░рд╛ рдЖрд░рдИрдПрд╕рдЯреА рд╕рд░реНрд╡рд░ рдПрдХ рд╡рд┐рдХрд▓реНрдк рдХреЙрд▓ рдХреЗ рд▓рд┐рдП 404 рдирд╣реАрдВ рдорд┐рд▓рд╛ рдЬрд╡рд╛рдм рджреЗрддрд╛ рд╣реИ ...

To avoid unwanted questions: the server is ok, it handles REST calls and CORS calls well, tested with $.ajax and a REST interface tester application too. рдЕрд╡рд╛рдВрдЫрд┐рдд рдкреНрд░рд╢реНрдиреЛрдВ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП: рд╕рд░реНрд╡рд░ рдареАрдХ рд╣реИ, рдпрд╣ рдЖрд░рдИрдПрд╕рдЯреА рдХреЙрд▓ рдФрд░ рд╕реАрдУрдЖрд░рдПрд╕ рдХреЙрд▓ рдХреЛ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕рдВрднрд╛рд▓рддрд╛ рд╣реИ, $ .ajax рдФрд░ рдПрдХ рдЖрд░рдИрдПрд╕рдЯреА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдкрд░реАрдХреНрд╖рдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд╕рд╛рде рднреА рдкрд░реАрдХреНрд╖рдг рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

en

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

@inf3rno try this one. @inf3rno рдЗрд╕реЗ рдЖрдЬрдорд╛рдПрдВред

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Content-Type');
header('Access-Control-Allow-Methods: POST');

This isn't Backbone issue at all. рдпрд╣ рдмреИрдХрдмреЛрди рдЗрд╢реНрдпреВ рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВ рд╣реИред

en

рд╕рднреА 17 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

Look up how CORS works -- this is the expected "preflight" request рджреЗрдЦреЗрдВ рдХрд┐ CORS рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ -- рдпрд╣ рдЕрдкреЗрдХреНрд╖рд┐рдд "рдкреНрд░реАрдлреНрд▓рд╛рдЗрдЯ" рдЕрдиреБрд░реЛрдз рд╣реИ

https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS#Preflighted_requests https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS#Preflighted_requests

en

рдореИрдВ рдЗрд╕ рд░рд┐рдлрд╝реНрд▓рд╛рдЗрдЯ рдЕрдиреБрд░реЛрдз рд╕реЗ рдХреИрд╕реЗ рдмрдЪ рд╕рдХрддрд╛ рд╣реВрдБ?

en

рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣рд╛рдВ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдХреЗрд╡рд▓ рдПрдХ "рд╕рд╛рдзрд╛рд░рдг рдЕрдиреБрд░реЛрдз" рднреЗрдЬреЗрдВ: https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS#Simple_requests

en

I tried this on server side to handle preflight calls: рдореИрдВрдиреЗ рдкреНрд░реАрдлреНрд▓рд╛рдЗрдЯ рдХреЙрд▓ рдХреЛ рд╕рдВрднрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд░реНрд╡рд░ рд╕рд╛рдЗрдб рдкрд░ рдпрд╣ рдХреЛрд╢рд┐рд╢ рдХреА:

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: X-Requested-With');
header('Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS');

but did not work, the browser does not send another request after the preflight... рд▓реЗрдХрд┐рди рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛, рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдкреНрд░реАрдлреНрд▓рд╛рдЗрдЯ рдХреЗ рдмрд╛рдж рдПрдХ рдФрд░ рдЕрдиреБрд░реЛрдз рдирд╣реАрдВ рднреЗрдЬрддрд╛ рд╣реИ ...

So you say that it is not possible with backbone.sync? рддреЛ рдЖрдк рдХрд╣рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ backbone.sync рдХреЗ рд╕рд╛рде рд╕рдВрднрд╡ рдирд╣реАрдВ рд╣реИ?
Then it is a bug I think... рдлрд┐рд░ рдпрд╣ рдПрдХ рдмрдЧ рд╣реИ рдЬреЛ рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ ...

en

рднрд▓реЗ рд╣реА, рдпрд╣ рд░реАрдврд╝ рдХреА рд╣рдбреНрдбреА рдХрд╛ рдореБрджреНрджрд╛ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рд╕реНрдЯреИрдХ рдУрд╡рд░рдлреНрд▓реЛ рдпрд╛ рдЖрдИрдЖрд░рд╕реА рдкрд░ рдкреВрдЫрдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реВрдВред

en

рдХреНрдпрд╛ рдЖрдк рдореБрдЭреЗ рд╕рдордЭрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рд░реАрдврд╝ рдХреА рд╣рдбреНрдбреА рдХрд╛ рдореБрджреНрджрд╛ рдХреНрдпреЛрдВ рдирд╣реАрдВ рд╣реИ?

en

Backbone.sync ( http://backbonejs.org/docs/backbone.html#section-134 ) рдХреЗ рд╕реНрд░реЛрдд рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрдврд╝реЗрдВ рдФрд░ рдЖрдк рджреЗрдЦреЗрдВрдЧреЗ рдХрд┐ рдмреИрдХрдмреЛрди рдмрд╕ рд╕рдм рдХреБрдЫ $.ajax рд╕реЗ рд╣реЛрдХрд░ рдЧреБрдЬрд░рддрд╛ рд╣реИред

en

@inf3rno try this one. @inf3rno рдЗрд╕реЗ рдЖрдЬрдорд╛рдПрдВред

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Headers: Content-Type');
header('Access-Control-Allow-Methods: POST');

This isn't Backbone issue at all. рдпрд╣ рдмреИрдХрдмреЛрди рдЗрд╢реНрдпреВ рдмрд┐рд▓реНрдХреБрд▓ рдирд╣реАрдВ рд╣реИред

en

These are my original headers without php: рдпреЗ PHP рдХреЗ рдмрд┐рдирд╛ рдореЗрд░реЗ рдореВрд▓ рд╢реАрд░реНрд╖рд▓реЗрдЦ рд╣реИрдВ:

HTTP/1.1 200 OK
Cache-Control: max-age=0, no-cache, no-store, must-revalidate
Pragma: no-cache
Content-Type: text/html
Expires: Wed, 11 Jan 1984 05:00:00 GMT
Server: Microsoft-IIS/7.5
X-Powered-By: PHP/5.3.8, ASP.NET
access-control-allow-origin: http://x.y.loc
Access-Control-Allow-Methods: POST, GET, PUT, DELETE, OPTIONS
Date: Fri, 17 May 2013 01:33:02 GMT
Content-Length: 0

I think my server is well configured, but I tried out the headers you gave, and they did not work... рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдореЗрд░рд╛ рд╕рд░реНрд╡рд░ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореИрдВрдиреЗ рдЖрдкрдХреЗ рджреНрд╡рд╛рд░рд╛ рджрд┐рдП рдЧрдП рд╢реАрд░реНрд╖рд▓реЗрдЦреЛрдВ рдХреЛ рдЖрдЬрдорд╛рдпрд╛, рдФрд░ рдЙрдиреНрд╣реЛрдВрдиреЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛ ...

Simple $.ajax calls work well, for example I load json files from the service with this: рд╕рд░рд▓ $.ajax рдХреЙрд▓ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП рдореИрдВ рдЗрд╕рдХреЗ рд╕рд╛рде рд╕реЗрд╡рд╛ рд╕реЗ json рдлрд╝рд╛рдЗрд▓реЗрдВ рд▓реЛрдб рдХрд░рддрд╛ рд╣реВрдВ:

define(function (require, exports, module) {
    var $ = require("jquery");

    module.exports = {
        load: function (name, _require, load, config) {
            var params = name.split("|");
            var method, url;
            if (params.length == 1) {
                method = "GET";
                url = params[0];
            }
            else {
                method = params[0];
                url = params[1];
            }
            $.ajax({
                url: url,
                type: method,
                dataType: "json"
            }).success(load).error(function (xhr, status, error) {
                    throw error;
                });
        }
    };

});

I tried out this with any request method, and they responded well... рдореИрдВрдиреЗ рдЗрд╕реЗ рдХрд┐рд╕реА рднреА рдЕрдиреБрд░реЛрдз рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде рдЖрдЬрдорд╛рдпрд╛, рдФрд░ рдЙрдиреНрд╣реЛрдВрдиреЗ рдЕрдЪреНрдЫреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреА ...

The collection.fetch() works well too, I have problems only with the model.save() ... рд╕рдВрдЧреНрд░рд╣ред рдкреНрд░рд╛рдкреНрдд () рднреА рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдореБрдЭреЗ рдХреЗрд╡рд▓ рдореЙрдбрд▓ рдХреЗ рд╕рд╛рде рд╕рдорд╕реНрдпрд╛ рд╣реИред рд╕рд╣реЗрдЬреЗрдВ () ...

I tried it this way, maybe I'm doing something wrong: рдореИрдВрдиреЗ рдЗрд╕реЗ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЖрдЬрдорд╛рдпрд╛, рд╢рд╛рдпрдж рдореИрдВ рдХреБрдЫ рдЧрд▓рдд рдХрд░ рд░рд╣рд╛ рд╣реВрдВ:

        var User = Backbone.Model.extend({
            urlRoot: Application.service.Authorization.User.create.url
        });
        var form = new UserForm({
            model: new User({
                email: "[email protected]",
                name: "test"
            })
        }).render();
        form.on("submit", function (user) {
            console.log(user.attributes);
            user.save(null, {
                success: function (model, response, options) {
                    console.log("success");
                },
                error: function (model, xhr, options) {
                    console.log("error");
                }
            });
        });

I got the attributes and "error" in console. рдореБрдЭреЗ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдЧреБрдг рдФрд░ "рддреНрд░реБрдЯрд┐" рдорд┐рд▓реА рд╣реИред I'll check what kind of error is.. рдореИрдВ рджреЗрдЦреВрдВрдЧрд╛ рдХрд┐ рдХрд┐рд╕ рддрд░рд╣ рдХреА рддреНрд░реБрдЯрд┐ рд╣реИ ..

en

You were right, thanks! рддреБрдо рд╕рд╣реА рдереЗ, рдзрдиреНрдпрд╡рд╛рдж! I added to server config the allow content-type, and it works now. рдореИрдВрдиреЗ рд╕рд░реНрд╡рд░ рдХреЙрдиреНрдлрд╝рд┐рдЧ рдореЗрдВ рдЕрдиреБрдорддрд┐ рд╕рд╛рдордЧреНрд░реА-рдкреНрд░рдХрд╛рд░ рдХреЛ рдЬреЛрдбрд╝рд╛, рдФрд░ рдпрд╣ рдЕрдм рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред Firebug is not the best, the Chrome console printed that the content-type is not allowed... рдлрд╛рдпрд░рдмрдЧ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИ, рдХреНрд░реЛрдо рдХрдВрд╕реЛрд▓ рдиреЗ рдореБрджреНрд░рд┐рдд рдХрд┐рдпрд╛ рд╣реИ рдХрд┐ рд╕рд╛рдордЧреНрд░реА-рдкреНрд░рдХрд╛рд░ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рд╣реИ ...

en

Many tanks! рдХрдИ рдЯреИрдВрдХ! :D :рдбреА

en

GET and POST requests requires quite different headers. GET рдФрд░ POST рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рдЕрд▓рдЧ рд╣реЗрдбрд░ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред When the API server uses cookies for authentication, the server should have Access-Control-Allow-Credentials: true header. рдЬрдм рдПрдкреАрдЖрдИ рд╕рд░реНрд╡рд░ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдХреЗ рд▓рд┐рдП cookies рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рддреЛ рд╕рд░реНрд╡рд░ рдореЗрдВ Access-Control-Allow-Credentials: true рд╣реЗрдбрд░ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред And off course you need to make a XHR request with withCredentials: true on client-side. рдФрд░ рдирд┐рд╢реНрдЪрд┐рдд рд░реВрдк рд╕реЗ рдЖрдкрдХреЛ рдХреНрд▓рд╛рдЗрдВрдЯ-рд╕рд╛рдЗрдб рдкрд░ withCredentials: true рдХреЗ рд╕рд╛рде рдПрдХреНрд╕рдПрдЪрдЖрд░ рдЕрдиреБрд░реЛрдз рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред When the API server uses Authorization header for BasicAuth request, you don't need withCredential . рдЬрдм API рд╕рд░реНрд╡рд░ BasicAuth рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП Authorization рд╣реЗрдбрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ withCredential рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред Instead, the Access-Control-Allow-Headers need to include Authorization in this case, just like рдЗрд╕рдХреЗ рдмрдЬрд╛рдп, Access-Control-Allow-Headers $ рдХреЛ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ Authorization рдХреЛ рд╢рд╛рдорд┐рд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬреИрд╕реЗ

header('Access-Control-Allow-Headers: Authorization, Content-Type');

Ah, it seems you solved the issue while I'm writing this. рдЖрд╣, рдРрд╕рд╛ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдЬрдм рдореИрдВ рдЗрд╕реЗ рд▓рд┐рдЦ рд░рд╣рд╛ рд╣реВрдВ рддреЛ рдЖрдкрдиреЗ рдЗрд╕ рдореБрджреНрджреЗ рдХреЛ рд╣рд▓ рдХрд░ рд▓рд┐рдпрд╛ рд╣реИред

en

рд╣рд╛рдБ, рд╡реИрд╕реЗ рднреА рдзрдиреНрдпрд╡рд╛рдж, рдЖрдкрдиреЗ рдмрд╣реБрдд рдорджрдж рдХреА!

en

@inf3rno Thanks so much for the comment about Chrome giving better error messages than Firebug! @ inf3rno рдлрд╝рд╛рдпрд░рдмрдЧ рд╕реЗ рдмреЗрд╣рддрд░ рддреНрд░реБрдЯрд┐ рд╕рдВрджреЗрд╢ рджреЗрдиреЗ рд╡рд╛рд▓реЗ рдХреНрд░реЛрдо рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЯрд┐рдкреНрдкрдгреА рдХреЗ рд▓рд┐рдП рдмрд╣реБрдд рдмрд╣реБрдд рдзрдиреНрдпрд╡рд╛рдж! That helped us solve the problem. рдЗрд╕рд╕реЗ рд╣рдореЗрдВ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдорд┐рд▓реАред

en

You're welcome! рдЖрдкрдХрд╛ рд╕реНрд╡рд╛рдЧрдд рд╣реИ! :-) :-)

en

Can someone please help on this issue? рдХреНрдпрд╛ рдХреЛрдИ рдХреГрдкрдпрд╛ рдЗрд╕ рдореБрджреНрджреЗ рдкрд░ рдорджрдж рдХрд░ рд╕рдХрддрд╛ рд╣реИ? http://stackoverflow.com/questions/32725249/cors-filter-issue-for-authentrypoint http://stackoverflow.com/questions/32725249/cors-filter-issue-for-authentrypoint

en

рдЕрдЧрд░ рдХрд┐рд╕реА рдФрд░ рдХреЛ рдпрд╣ рд╕рдорд╕реНрдпрд╛ рд╣реЛ рд░рд╣реА рд╣реИ рддреЛ рдореБрдЭреЗ рдПрдХреНрд╕реЗрд╕-рдХрдВрдЯреНрд░реЛрд▓-рдЕрдиреБрдорддрд┐-рд╡рд┐рдзрд┐рдпреЛрдВ рдХреА рдореЗрд░реА рд╕реВрдЪреА рдореЗрдВ "рдПрдХреНрд╕-рдПрдЪрдЯреАрдЯреАрдкреА-рд╡рд┐рдзрд┐-рдУрд╡рд░рд░рд╛рдЗрдб" рдЬреЛрдбрд╝рдирд╛ рдкрдбрд╝рд╛, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рддрдм рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдЬрдм рдЖрдк рдмреИрдХрдмреЛрди.рдПрдореБрд▓реЗрдЯ рдПрдЪрдЯреАрдЯреАрдкреА = рд╕рддреНрдп рд╕реЗрдЯ рдХрд░рддреЗ рд╣реИрдВред

en
рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

g00fy- picture g00fy-  ┬╖  9рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

PavelKoroteev picture PavelKoroteev  ┬╖  10рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

jonathan picture jonathan  ┬╖  11рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

rafde picture rafde  ┬╖  9рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

chaimpeck picture chaimpeck  ┬╖  8рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ