рдореИрдВ рд╡рд┐рднрд┐рдиреНрди рдбреЛрдореЗрди рд╕реЗ WCF рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдВрднрд╛рд╡рд┐рдд рджреГрд╖реНрдЯрд┐рдХреЛрдгреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛ред рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рдореБрдЭреЗ рдЬреЛ рдЬрд╛рдирдХрд╛рд░реА рдорд┐рд▓реА рд╡рд╣ рдпрд╛ рддреЛ рдЕрдзреВрд░реА рдереА рдпрд╛ рдЙрд╕рдореЗрдВ рдЕрддреНрдпрдзрд┐рдХ рдорд╛рддреНрд░рд╛ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдереА, рдЬрд┐рд╕реЗ рд╕рдордЭрдирд╛ рдореБрд╢реНрдХрд┐рд▓ рдерд╛ред рдореИрдВ WCF рдФрд░ AJAX POST рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рдмреАрдЪ рдмрд╛рддрдЪреАрдд рдХреЗ рдХрдИ рддрд░реАрдХреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВ, рдЬрд┐рд╕рдореЗрдВ рдХреБрдХреАрдЬрд╝ рдФрд░ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╢рд╛рдорд┐рд▓ рд╣реИред
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╕реБрд░рдХреНрд╖рд╛ рдХрд╛рд░рдгреЛрдВ рд╕реЗ AJAX рдХреЙрд▓ рдХрд┐рд╕реА рдЕрдиреНрдп рдбреЛрдореЗрди рдкрд░ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, CORS рдорд╛рдирдХ ( рд╡рд┐рдХреА , рдореЛрдЬрд╝рд┐рд▓рд╛ ) рдХрд╛ рдЖрд╡рд┐рд╖реНрдХрд╛рд░ рдФрд░ рд╡рд┐рдореЛрдЪрди рдХрд┐рдпрд╛ рдЧрдпрд╛ред рдЗрд╕ рдорд╛рдирдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдПрдХреНрд╕реЗрд╕ рдХрд░рдиреЗ рдФрд░ рдкреНрд░рддрд┐рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╢рд┐рд╖реНрдЯ HTTP рд╣реЗрдбрд░ рдХреЗ рдЙрдкрдпреЛрдЧ рд╕реЗ рд╣реИред рдЗрд╕ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдПрдХ рд╕рд░рд▓ рд╕рдВрдЪрд╛рд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдЕрд░реНрде рд╣реИ:
рдХреНрд▓рд╛рдЗрдВрдЯ (рдмреНрд░рд╛рдЙрдЬрд╝рд░)
Origin
HTTP HTTP рд╣реЗрдбрд░ рдХреЗ рд╕рд╛рде рдПрдХ рдХрдиреЗрдХреНрд╢рди рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИ, рд╕рд░реНрд╡рд░ рдХреЛ
Access-Control-Allow-Origin
рд╣реЗрдбрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЬрд╡рд╛рдм рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдПред рдПрдХ рдкрддреЗ рд╕реЗ рдЕрдиреБрд░реЛрдз / рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЬреЛрдбрд╝реА рдХрд╛ рдЙрджрд╛рд╣рд░рдг
foo.example
foo.example
рд╕реЗрд╡рд╛ рдХреЗ рд▓рд┐рдП
bar.other/resources/public-data
bar.other/resources/public-data
:
рдкреНрд░рд╢реНрди:
GET / рд╕рдВрд╕рд╛рдзрди / рд╕рд╛рд░реНрд╡рдЬрдирд┐рдХ рдбреЗрдЯрд╛ / HTTP / 1.1
рд╣реЛрд╕реНрдЯ: bar.other
рдореВрд▓:foo.example
[рдЕрдиреНрдп рд╣реЗрдбрд░]
рдЙрддреНрддрд░ рд╣реИ:
HTTP / 1.1 200 рдареАрдХ рд╣реИ
рджрд┐рдирд╛рдВрдХ: рд╕реЛрдо, режрез рджрд┐рд╕рдВрдмрд░ реирежреж 00: 00:23:53 GMT
рдкреНрд░рд╡реЗрд╢-рдирд┐рдпрдВрддреНрд░рдг-рдЕрдиреБрдорддрд┐-рдЙрддреНрдкрддреНрддрд┐: *
рд╕рд╛рдордЧреНрд░реА-рдкреНрд░рдХрд╛рд░: рдЖрд╡реЗрджрди / xml
[XML рдбреЗрдЯрд╛]
рд╕реБрд░реНрдЦрд┐рдпреЛрдВ рдореЗрдВ
-
Access-Control-Allow-Origin
- рдпрд╣ рд╣реЗрдбрд░ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХрд┐рди рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЗ рдЕрдиреБрд░реЛрдз рдЖ рд╕рдХрддреЗ рд╣реИрдВред*
рдпрд╛ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдбреЛрдореЗрди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЙрджрд╛редfoo.example
foo.example
ред рдпрд╣ рд╢реАрд░реНрд╖рд▓реЗрдЦ рдХреЗрд╡рд▓ рдПрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рдореЗрдВ рдХреЗрд╡рд▓ рдПрдХ рдорд╛рди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд рдбреЛрдореЗрди рд╕реВрдЪреА рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХреА рдЬрд╛ рд╕рдХрддреАред -
Access-Control-Allow-Methods
- рдпрд╣ рд╣реЗрдбрд░ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рд╕рд░реНрд╡рд░ рдХреЗ рд╕рд╛рде рд╕рдВрд╡рд╛рдж рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рди рддрд░реАрдХреЛрдВ рдХрд╛ рдЗрд╕реНрддреЗрдорд╛рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рд╣рдо рдЦреБрдж рдХреЛ рдирд┐рдореНрди рддрдХ рд╕реАрдорд┐рдд рд░рдЦрддреЗ рд╣реИрдВ:POST,GET,OPTIONS
, рд▓реЗрдХрд┐рди рдЖрдкPUT
, рдФрд░DELETE
, рдФрд░ рдЕрдиреНрдп рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред -
Access-Control-Allow-Headers
рд╣реЗрдбрд░реНрд╕ - рдпрд╣ рд╣реЗрдбрд░ рдЙрдкрд▓рдмреНрдз рд╣реЗрдбрд░ рдХреА рд╕реВрдЪреА рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП,Content-Type
, рдЬреЛ рдЖрдкрдХреЛapplication/json
рд▓рд┐рдП рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреНрд░рдХрд╛рд░ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред -
Access-Control-Allow-Credentials
- рдпрд╣ рд╣реЗрдбрд░ рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдХреБрдХреАрдЬрд╝ рдФрд░ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рд╣реЗрдбрд░ рдХреА рдЕрдиреБрдорддрд┐ рд╣реИ рдпрд╛ рдирд╣реАрдВред рд╕рдВрднрд╛рд╡рд┐рдд рдореВрд▓реНрдпtrue
рдФрд░false
ред рдорд╣рддреНрд╡рдкреВрд░реНрдг: рдбреЗрдЯрд╛ рдХреЗрд╡рд▓ рддрднреА рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдЬрдмAccess-Control-Allow-Origin
рд╣реЗрдбрд░ рдореЗрдВ рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдбреЛрдореЗрди рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реЛ, рдпрджрд┐*
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣реЗрдбрд░ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдФрд░ рдХреЛрдИ рдбреЗрдЯрд╛ рдкреНрд░рд╕рд╛рд░рд┐рдд рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдкреНрд░рддрд┐рдмрдВрдз рд▓рдЧрд╛рддрд╛ рд╣реИред рдпрджрд┐ рд╡рд╣ рд╣реЗрдбрд░ рдореЗрдВ рдХреБрдЫ рдкрд╕рдВрдж рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ, рддреЛ рдЙрд╕рдиреЗ рдпрд╣ рдбреЗрдЯрд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдирд╣реАрдВ рджрд┐рдпрд╛ рд╣реИ (рдЬрдм рддрдХ рдХрд┐ рдЖрд╡рд╢реНрдпрдХ
Access-Control-Allow-Headers
рд╡рд╛рдкрд╕ рдирд╣реАрдВ рдЖрддрд╛ рд╣реИ, рдпрд╛ рдпрджрд┐
Access-Control-Allow-Credentials
рдФрд░ рд╕рд╣реА
Access-Control-Allow-Origin
рдирд╣реАрдВ рд╣реИ, рддреЛ рд╕рд░реНрд╡рд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ)
Access-Control-Allow-Origin
: рдХрд┐рд╕реА рдЕрдиреНрдп рдбреЛрдореЗрди рдХреЗ рд▓рд┐рдП
POST
рдЕрдиреБрд░реЛрдз рд╕реЗ рдкрд╣рд▓реЗ, рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдкрд╣рд▓реЗ рд╕реЗрд╡рд╛ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рдЕрдиреБрдордд рддрд░реАрдХреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рдЕрдиреБрд░реЛрдз рдХрд░реЗрдЧрд╛ред
WCF
рдЗрд╕ рд╡рд┐рд╖рдп рдкрд░ рдЕрд▓рдЧ-рдЕрд▓рдЧ рдЧреБрдгрд╡рддреНрддрд╛ рдХреА рдЬрд╛рдирдХрд╛рд░реА рдХреА рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд░рд╛рд╢рд┐ рд╣реИред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, WCF рдорд╛рдирдХ рддрд░реАрдХреЛрдВ рд╕реЗ рдЗрди рд╣реЗрдбрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрдИ рд╡рд┐рдХрд▓реНрдк рд╣реИрдВред рдореИрдВ рдЙрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рдХреЛ рдЖрдкрдХреЗ рдзреНрдпрд╛рди рдореЗрдВ рд▓рд╛рддрд╛ рд╣реВрдВред
Web.config рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдорд╛рдзрд╛рдиред
рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реЗрдбрд░ рдХреЛ рд╕реАрдзреЗ web.config рдореЗрдВ рдЬреЛрдбрд╝рдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред
<system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="http://foo.example" /> <add name="Access-Control-Allow-Headers" value="Content-Type" /> <add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS" /> <add name="Access-Control-Allow-Credentials" value="true" /> </customHeaders> </httpProtocol> </system.webServer>
рдпрд╣ рдЕрдкрдиреА рд╕рд╛рджрдЧреА рдФрд░ рдЕрдирдореНрдпрддрд╛ рд╕реЗ рдкреНрд░рддрд┐рд╖реНрдард┐рдд рд╣реИред рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ, рдЗрд╕ рд╡рд┐рд╢реЗрд╖ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдпрджрд┐ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рд╕рдВрднрд╡ рдбреЛрдореЗрди рд╣реИрдВ, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣ рдкреВрд░реА рд╕рд╛рдЗрдЯ (рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рдорд╛рдорд▓реЗ рдореЗрдВ) рдХреЛ CORS рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
Global.asax рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдорд╛рдзрд╛рди
рдЗрд╕ рд╕рдорд╛рдзрд╛рди рдореЗрдВ Global.asax.cs рдореЗрдВ рдХреЛрдб рд▓рд┐рдЦрдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИ рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рд╣реЗрдбрд░ рдЬреЛрдбрд╝рддрд╛ рд╣реИред
protected void Application_BeginRequest(object sender, EventArgs e) { var allowedOrigins = new [] { "http://foo.example", "http://bar.example" }; var request = HttpContext.Current.Request; var response = HttpContext.Current.Response; var origin = request.Headers["Origin"]; if (origin != null && allowedOrigins.Any(x => x == origin)) { response.AddHeader("Access-Control-Allow-Origin", origin); response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); response.AddHeader("Access-Control-Allow-Headers", "Content-Type, X-Requested-With"); response.AddHeader("Access-Control-Allow-Credentials", "true"); if (request.HttpMethod == "OPTIONS") { response.End(); } } }
рдпрд╣ рд╕рдорд╛рдзрд╛рди рдХрдИ рдбреЛрдореЗрди рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкреВрд░реА рд╕рд╛рдЗрдЯ рдкрд░ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред рдмреЗрд╢рдХ, рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕реЗрд╡рд╛рдУрдВ рдХреЗ рд▓рд┐рдП рд╕рднреА рд╢рд░реНрддреЛрдВ рдХреЛ рд╡рд╣реАрдВ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдореЗрд░реА рд░рд╛рдп рдореЗрдВ рдпрд╣ рдЕрдиреБрдордд рд╕реЗрд╡рд╛рдУрдВ рдХреА рд╕реВрдЪреА рдмрдирд╛рдП рд░рдЦрдиреЗ рдореЗрдВ рдЕрд╕реБрд╡рд┐рдзрд╛рдУрдВ рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реИред
WCF рд╕реЗрд╡рд╛ рдХреЛрдб рдореЗрдВ рд╣реЗрдбрд░ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рд╕рд╛рде рд╕рдорд╛рдзрд╛рди
рдпрд╣ рд╕рдорд╛рдзрд╛рди рдХреЗрд╡рд▓ рдкрд┐рдЫрд▓реЗ рдПрдХ рд╕реЗ рднрд┐рдиреНрди рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рд╣реЗрдбрд░ рдХрд┐рд╕реА рд╡рд┐рд╢реЗрд╖ рд╕реЗрд╡рд╛ рдпрд╛ рд╡рд┐рдзрд┐ рдХреЗ рд▓рд┐рдП рдЬреЛрдбрд╝реЗ рдЬрд╛рддреЗ рд╣реИрдВред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рд╕рдорд╛рдзрд╛рди рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
[ServiceContract] public class MyService { [OperationContract] [WebInvoke(Method = "POST", ...)] public string DoStuff() { AddCorsHeaders(); return "<Data>"; } private void AddCorsHeaders() { var allowedOrigins = new [] { "http://foo.example", "http://bar.example" }; var request = WebOperationContext.Current.IncomingRequest; var response = WebOperationContext.Current.OutgoingResponse; var origin = request.Headers["Origin"]; if (origin != null && allowedOrigins.Any(x => x == origin)) { response.AddHeader("Access-Control-Allow-Origin", origin); response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS"); response.AddHeader("Access-Control-Allow-Headers", "Content-Type, X-Requested-With"); response.AddHeader("Access-Control-Allow-Credentials", "true"); if (request.HttpMethod == "OPTIONS") { response.End(); } } } }
рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЖрдкрдХреЛ рд╕реЗрд╡рд╛ рдпрд╛ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рдПрдХ рд╡рд┐рдзрд┐ рдХреЗ рдврд╛рдВрдЪреЗ рдореЗрдВ рдХреЙрд░реНрд╕ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рд╕реАрдорд┐рдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдореБрдЦреНрдп рдиреБрдХрд╕рд╛рди рдпрд╣ рд╣реИ рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рд╕реЗрд╡рд╛ рдкрджреНрдзрддрд┐ рдореЗрдВ
AddCorsHeaders
рдХреЙрд▓
AddCorsHeaders
рдЖрд╡рд╢реНрдпрдХ рд╣реИред рдкреНрд▓рд╕ - рдЙрдкрдпреЛрдЧ рдореЗрдВ рдЖрд╕рд╛рдиреАред
рджреЗрд╢реА EndPointBehavior рдФрд░ DispatchMessageInspector рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдорд╛рдзрд╛рди
рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХрд╛ рд╡рд┐рд╕реНрддрд╛рд░ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП WCF рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
2 рд╡рд░реНрдЧ
EnableCorsBehavior
рдмрдирд╛рдП рдЧрдП рд╣реИрдВ:
using System; using System.ServiceModel.Channels; using System.ServiceModel.Configuration; using System.ServiceModel.Description; using System.ServiceModel.Dispatcher; namespace My.Web.Cors { public class EnableCorsBehavior : BehaviorExtensionElement, IEndpointBehavior { public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { endpointDispatcher.DispatchRuntime.MessageInspectors.Add(new EnableCorsMessageInspector()); } public void Validate(ServiceEndpoint endpoint) { } public override Type BehaviorType { get { return typeof(EnableCorsBehavior); } } protected override object CreateBehavior() { return new EnableCorsBehavior(); } } }
рдФрд░
EnableCorsMessageInspector
:
using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.ServiceModel; using System.ServiceModel.Channels; using System.ServiceModel.Dispatcher; namespace My.Web.Cors { public class EnableCorsMessageInspector : IDispatchMessageInspector { public object AfterReceiveRequest(ref Message request, IClientChannel channel, InstanceContext instanceContext) { var allowedOrigins = new [] { "http://foo.example", "http://bar.example" }; var httpProp = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]; if (httpProp != null) { string origin = httpProp.Headers["Origin"]; if (origin != null && allowedOrigins.Any(x => x == origin)) { return origin; } } return null; } public void BeforeSendReply(ref Message reply, object correlationState) { string origin = correlationState as string; if (origin != null) { HttpResponseMessageProperty httpProp = null; if (reply.Properties.ContainsKey(HttpResponseMessageProperty.Name)) { httpProp = (HttpResponseMessageProperty)reply.Properties[HttpResponseMessageProperty.Name]; } else { httpProp = new HttpResponseMessageProperty(); reply.Properties.Add(HttpResponseMessageProperty.Name, httpProp); } httpProp.Headers.Add("Access-Control-Allow-Origin", origin); httpProp.Headers.Add("Access-Control-Allow-Credentials", "true"); httpProp.Headers.Add("Access-Control-Request-Method", "POST,GET,OPTIONS"); httpProp.Headers.Add("Access-Control-Allow-Headers", "X-Requested-With,Content-Type"); } } } }
рдмрдирд╛рдпреЗ рдЧрдП
EnableCorsBehavior
рдХреЛ
web.config
рдЬреЛрдбрд╝реЗрдВ:
<system.serviceModel> ... <extensions> <behaviorExtensions> <add name="crossOriginResourceSharingBehavior" type="My.Web.Cors.EnableCorsBehavior, My.Web, Version=1.0.0.0, Culture=neutral" /> </behaviorExtensions> </extensions> ... </system.serviceModel>
EnableCorsBehavior
рдХреЗ рд▓рд┐рдП рдмрдирд╛рдП рдЧрдП рдПрдХреНрд╕рдЯреЗрдВрд╢рди рдХреЛ рд╣рдорд╛рд░реЗ
Endpoint
рдХреЗ
Behavior
рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдореЗрдВ рдЦреЛрдЬреЗрдВ рдФрд░ рдЬреЛрдбрд╝реЗрдВ
<system.serviceModel> <services> <service name="My.Web.Services.MyService"> <endpoint address="" behaviorConfiguration="My.Web.Services.MyService" binding="webHttpBinding" contract="My.Web.Services.MyService" /> </service> </services> ... <behaviors> ... <endpointBehaviors> ... <behavior name="My.Web.Services.MyService"> <webHttp/> <crossOriginResourceSharingBehavior /> <!-- --> </behavior> ... </endpointBehaviors> ... </behaviors> ... </system.serviceModel>
рд╣рдореЗрдВ рдХреЗрд╡рд▓
OPTIONS
рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрдиреБрд░реЛрдз рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдореИрдВрдиреЗ рд╕рдмрд╕реЗ рд╕рд░рд▓ рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛: рд╕реЗрд╡рд╛ рдХреЗ рдирд┐рдХрд╛рдп рдореЗрдВ рдПрдХ
OPTIONS
рдЕрдиреБрд░реЛрдз рд╣реИрдВрдбрд▓рд░ рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред
[OperationContract] [WebInvoke(Method = "OPTIONS", UriTemplate = "*")] public void GetOptions() { // EnableCorsMessageInspector }
рдмреЗрд╢рдХ, рдкреНрд░реАрдлрд╝рд▓рд╛рдЗрдЯ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╕рдорд╛рди WCF рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╣реИ, рдЙрдирдореЗрдВ рд╕реЗ рдПрдХ рдХреЛ рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ рд╕рдВрджрд░реНрднреЛрдВ рдХреА рд╕реВрдЪреА рд╕реЗ рд╕рдВрджрд░реНрдн рджреНрд╡рд╛рд░рд╛ рдкрдврд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдореБрдЦреНрдп рдиреБрдХрд╕рд╛рди рд╕реЗрд╡рд╛ рдХреЗ рд╢рд░реАрд░ рдФрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЛрдб рдХреА рдПрдХ рдмрдбрд╝реА рд░рд╛рд╢рд┐ рдХреЗ рд▓рд┐рдП
GetOptions
рд╡рд┐рдзрд┐ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рджреВрд╕рд░реА рдУрд░, рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣рдореЗрдВ рд╕реЗрд╡рд╛ рдХреЗ рддрд░реНрдХ рдФрд░ рд╕рдВрдЪрд╛рд░ рдХреЗ рддрд░реНрдХ рдХреЛ рд▓рдЧрднрдЧ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдЕрд▓рдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдФрд░ рдмреНрд░рд╛рдЙрдЬрд╝рд░реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рд╢рдмреНрдж
рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдФрд░ рдХреБрдХреА рдбреЗрдЯрд╛ рднреЗрдЬрдиреЗ рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдЖрд╡рд╢реНрдпрдХ рд╣реИ рдХрд┐
withCredentials
рдореЗрдВ
withCredentials
рдзреНрд╡рдЬ рдХреЛ
true
рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЧрдпрд╛
true
ред рдореБрдЭреЗ рд▓рдЧрддрд╛ рд╣реИ рдХрд┐ рдмрд╣реБрдд рд╕реЗ рд▓реЛрдЧ AJAX рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП jQuery рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рдЙрджрд╛рд╣рд░рдг рджреВрдВрдЧрд╛:
$.ajax({ type: 'POST', cache: false, dataType: 'json', xhrFields: { withCredentials: true }, contentType: 'application/json; charset=utf-8', url: options.serviceUrl + '/DoStuff' });
рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдбреЗрдЯрд╛ рднреЗрдЬрдиреЗ рд╕реЗ рд╕рдВрдмрдВрдзрд┐рдд рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреЗрд╡рд▓ рд╕рдВрд╕реНрдХрд░рдг 10 рд╕реЗ IE рдХреЗ рд▓рд┐рдП рдЙрдкрд▓рдмреНрдз рд╣реЛ рдЧрдИ, IE8 / 9 рдмреНрд░рд╛рдЙрдЬрд╝рд░ рдЗрд╕ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рднреЗрдЬрдиреЗ рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдХреЗрд╡рд▓ GET рдФрд░ POST рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдкреНрд░рд╛рдзрд┐рдХрд░рдг
рдЙрдкрд░реЛрдХреНрдд рд╕рднреА рддрд░реАрдХреЛрдВ рдореЗрдВ, рдореБрдЦреНрдп рд╕рд╛рдЗрдЯ рд╕реЗ рдкреНрд░рдорд╛рдгреАрдХрд░рдг рдбреЗрдЯрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдореБрдЦреНрдп рд╕рд╛рдЗрдЯ рдкрд░ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рд╣реЛрдирд╛
bar.other
bar.other
, рд╣рдо рд╕рд╛рдЗрдЯ рд╕реЗ Ajax рдЕрдиреБрд░реЛрдз рджреНрд╡рд╛рд░рд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдбреЗрдЯрд╛ рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реИрдВ
foo.example
foo.example
ред рдореЗрд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рд╕реВрдЪрдирд╛рдПрдВ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдФрд░ рдШрдЯрдирд╛рдУрдВ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЬрдмрдХрд┐ рдПрдХ рд╣реА рд╡реНрдпрд╡рд╕рд╛рдп рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ рд░рд╣рдиреЗ рд╡рд╛рд▓реЗ рд╕рд╛рдЗрдЯреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдкрд░, рд▓реЗрдХрд┐рди рд╡рд┐рднрд┐рдиреНрди рдбреЛрдореЗрди рдФрд░ рдкреНрд▓реЗрдЯрдлрд╛рд░реНрдореЛрдВ рдкрд░ рд╕реНрдерд┐рдд рд╣реИред рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рдЙрд▓реНрд▓реЗрдЦ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдпрд╣рд╛рдВ рдкреНрд░рдореБрдЦ рдмрд┐рдВрджреБ рд╣реЗрдбрд░
Access-Control-Allow-Credentials
рдФрд░
XmlHttpRequest
рдзреНрд╡рдЬ рдХреЛ
withCredentials=true
рд╕реЗрдЯ рдХрд░рдирд╛
withCredentials=true
ред
рд╕реВрддреНрд░реЛрдВ рдХреА рд╕реВрдЪреА
- code.msdn.microsoft.com/windowsdesktop/Implementing-CORS-support-c1f9cd4b - рд╕рднреА рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП MessageInspector рдХреЗ рдкреВрд░реНрдг рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХ рд▓реЗрдЦ
- enable-cors.org/server_wcf.html - рдЕрдкрдиреЗ рд╕реНрд╡рдпрдВ рдХреЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдФрд░ MessageInspector рд▓рд┐рдЦрдиреЗ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдЫреЛрдЯреА рдкреБрд╕реНрддрд┐рдХрд╛, рд╡рд┐рдХрд▓реНрдк рдЕрдиреБрд░реЛрдзреЛрдВ рдХреА рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рдирд╣реАрдВ рд░рдЦрддрд╛ рд╣реИ, рдФрд░ рдореВрд▓ рдбреЛрдореЗрди рдЪреЗрдХ / рдЪрдпрди рдХреЗ рдЙрдкрдпреЛрдЧ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ
- developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS#Access-Control-Allow-Headers - CORS рдкрд░ рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд╕рдмрд╕реЗ рд╡реНрдпрд╛рдкрдХ рд╕реНрд░реЛрддреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ