„AngularJS“ atlieka „HTTP OPTIONS“ užklausą dėl tarpinio šaltinio išteklių.

Bandau sukonfigūruoti „AngularJS“ ryšį su kryžminio šaltinio ištekliais, kur priimančioji ištekliai, teikiantys mano šablonų failus, yra kitame domene, todėl XHR prašymas, vykdomas kampiniu, turi būti kryžminis. Prie serverio pridėjau atitinkamą CORS antraštę HTTP užklausai atlikti darbą, tačiau atrodo, kad jis neveikia. Problema ta, kad tikrinant HTTP užklausas naršyklėje (chromo), užklausa, siunčiama į turto failą, yra OPTIONS užklausa (tai turėtų būti GET užklausa).

Nesu tikras, ar tai yra „AngularJS“ klaida, ar turiu konfigūruoti kažką. Iš to, ką suprantu, „XHR“ pakuotė negali pateikti „OPTIONS HTTP“ užklausos, todėl atrodo, kad naršyklė bando išsiaiškinti, ar turtas yra „pakrautas“, kol jis atlieka GET užklausą. Tokiu atveju turiu nustatyti CORS antraštę (Access-Control-Allow-Origin: http://asset.host ... ) Naudodamiesi išteklių ištekliais?

252
24 авг. nustatyti matsko 24 rug . 2012-08-24 18:02 '12 at 18:02 2012-08-24 18:02
@ 14 atsakymų

„OPTIONS“ užklausa jokiu būdu nėra „AngularJS“ klaida, nes „Cross-Origin Resource Sharing“ standartas reikalauja, kad naršyklės elgtųsi. Žiūrėkite šį dokumentą: https://developer.mozilla.org/en-US/docs/HTTP_access_control , kur skiltyje „Peržiūra“ sakoma:

„Cross-Origin“ išteklių pasidalijimo standartas veikia pridedant naują HTTP protokolą, kuris leidžia serveriams aprašyti šaltinių rinkinį, kuriam leidžiama skaityti šią informaciją naudodami žiniatinklio naršyklę. Be to, HTTP užklausos metodams, kurie gali sukelti šalutinį poveikį naudotojo duomenims (konkrečiai - HTTP metodams, išskyrus GET, arba naudoti POST su kai kuriais MIME tipais). Specifikacijoje reikalaujama, kad naršyklės „paprašytų“ užklausos, paprašydamos palaikomų metodų iš serverio su HTTP OPTIONS užklausos antrašte, o tada patvirtinus serverį, siunčiantį tikrąjį užklausą su faktiniu HTTP užklausos metodu. Serveriai taip pat gali pranešti klientams, ar „kredencialai“ (įskaitant slapukus ir HTTP autentiškumą) turi būti siunčiami su užklausomis.

Labai sunku pateikti bendrą sprendimą, kuris veiktų visuose WWW serveriuose, nes nustatymas priklausys nuo paties serverio ir HTTP veiksmažodžių, kuriuos ketinate palaikyti. Norėčiau patarti perskaityti šį nuostabų straipsnį ( http://www.html5rocks.com/en/tutorials/cors/ ), kuris turi daug daugiau informacijos apie antraštes, kurias turėtų siųsti serveris.

218
24 авг. atsakymą pateikė pkozlowski.opensource 24 rug . 2012-08-24 18:23 '12, 18:23, 2012-08-24 18:23

Angular 1.2.0rc1 + jums reikia pridėti ištekliųUrlWhitelist.

1.2: jie pridėjo „escapeForRegexp“ funkciją taip, kad jums nereikėtų slėpti stygos. Galite tiesiog pridėti URL tiesiogiai

 'http://sub*.assets.example.com/**' 

būtinai pridėkite ** pagalbiniams aplankams. Čia yra darbas, skirtas 1.2: http://jsbin.com/olavok/145/edit


1.2.0rc: jei vis dar esate versijoje rc, 1.2.0rc1 kampinis sprendimas atrodo taip:

border=0
 .config(['$sceDelegateProvider', function($sceDelegateProvider) { $sceDelegateProvider.resourceUrlWhitelist(['self', /^https?:\/\/(cdn\.)?yourdomain.com/]); }]) 

Čia yra pavyzdys jsbin, kur jis veikia 1.2.0rc1: http://jsbin.com/olavok/144/edit


Išankstinis 1.2: senesnėms versijoms (ref http://better-inter.net/enaging-cors-in-angular-js/ ) į savo konfigūraciją turite pridėti šias 2 eilutes:

 $httpProvider.defaults.useXDomain = true; delete $httpProvider.defaults.headers.common['X-Requested-With']; 

Čia yra pavyzdys jsbin, kuriame jis veikia versijose iki 1.2: http://jsbin.com/olavok/11/edit

66
15 мая '13 в 19:40 2013-05-15 19:40 atsakymą įteikė JStark gegužės 15 d. 13 val. 19.40 2013-05-15 19:40

PASTABA. Nežinote, ar jis veikia su naujausia „Angular“ versija.

ORIGINALAS:

Taip pat galima pakeisti OPTIONS užklausą (ji buvo išbandyta tik „Chrome“):

 app.config(['$httpProvider', function ($httpProvider) { //Reset headers to avoid OPTIONS request (aka preflight) $httpProvider.defaults.headers.common = {}; $httpProvider.defaults.headers.post = {}; $httpProvider.defaults.headers.put = {}; $httpProvider.defaults.headers.patch = {}; }]); 
61
11 дек. atsakymą pateikė vartotojo2899845 11 dec. 2013-12-11 13:07 '13, 13:07, 2013-12-11 13:07

Jūsų paslauga turėtų atsakyti į OPTIONS užklausą su antraštėmis, tokiomis kaip:

 Access-Control-Allow-Origin: [the same origin from the request] Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: [the same ACCESS-CONTROL-REQUEST-HEADERS from request] 

Čia yra geras dokumentas: http://www.html5rocks.com/en/tutorials/cors/#toc-adding-cors-support-to-the-server

34
21 апр. atsakymą pateikė user2304582 21 balandis 2013-04-21 17:51 '13, 17:51, 2013-04-21 17:51

Tame pačiame dokumente sakoma

Skirtingai nuo paprastų užklausų (žr. Aukščiau), „iš anksto užpildyti“ užklausos pirmiausia siunčia HTTP OPTIONS užklausos antraštę į išteklių kitame domene, kad nustatytų, ar saugu siųsti šį prašymą. Tokiu būdu priešpriešiniai prašymai pateikiami prieš tai, nes jie gali turėti įtakos naudotojo duomenims. Visų pirma, prašymas pateikiamas prieš, jei:

Naudoja ne GET ar POST metodus. Be to, jei POST naudojamas prašymo duomenims siųsti, naudojant turinio tipą, išskyrus taikomąją / x-www-formą-urlencoded, daugiapartę / formą arba tekstą / paprastą. jei POST užklausa siunčia XML serverį naudodama / xml arba text / xml programą, prašymas yra parengtas.

Jis nustato priskirtus antraštes užklausoje (pvz., Prašyme naudojama antraštė, pvz., X-PINGOTHER)

Kai pradiniame gauti užklausą nėra priskirtų antraštių, naršyklė neturėtų prašyti parametrų, kuriuos ji dabar daro. Problema ta, kad ji generuoja X-Requested-With antraštę, kuri verčia parinktį „Options“. Žr. Https://github.com/angular/angular.angular.js/pull/1454 , kaip pašalinti šią antraštę

20
09 марта '13 в 5:45 2013-03-09 05:45 atsakymą pateikė „ Grum Ketema“ kovo 9 d. 13 d. 5:45 2013-03-09 05:45

Jei naudojate „nodeJS“ serverį, galite naudoti šią biblioteką, tai puikiai tinka man https://github.com/expressjs/cors

 var express = require('express') , cors = require('cors') , app = express(); app.use(cors()); 

ir paleidus npm update .

10
14 окт. atsakymas pateikiamas Zakaria.dem 14 okt. 2016-10-14 20:11 '16 at 8:11 pm 2016-10-14 20:11

Tai nustatė mano problemą:

 $http.defaults.headers.post["Content-Type"] = "text/plain"; 
10
25 февр. atsakymą pateikė Cem Arguvanlı 25 vasaris 2016-02-25 15:59 '16 at 15:59 2016-02-25 15:59

Štai kaip aš išsprendžiau šią problemą ASP.NET.

  • Pirmiausia reikia pridėti „ Microsoft.AspNet.WebApi.Cors“ nugeto paketą .

  • Tada redaguokite failą App_Start WebApiConfig.cs

     public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.EnableCors(); ... } } 
  • Pridėkite šį atributą į valdiklio klasę.

     [EnableCors(origins: "*", headers: "*", methods: "*")] public class MyController : ApiController { [AcceptVerbs("POST")] public IHttpActionResult Post([FromBody]YourDataType data) { ... return Ok(result); } } 
  • Aš galėčiau siųsti jsoną tokiam veiksmui

     $http({ method: 'POST', data: JSON.stringify(data), url: 'actionurl', headers: { 'Content-Type': 'application/json; charset=UTF-8' } }).then(...) 

Nuoroda: įgalinkite kryžminės kilmės užklausas ASP.NET Web API 2

4
23 июня '16 в 17:45 2016-06-23 17:45 atsakymas pateikiamas birželio 23 d. 16 d. 17:45 val. 2016-06-23 17:45

Kažkaip tai pataisiau keisdamas

 <add name="Access-Control-Allow-Headers" value="Origin, X-Requested-With, Content-Type, Accept, Authorization" /> 

į

 <add name="Access-Control-Allow-Headers" value="Origin, Content-Type, Accept, Authorization" /> 
2
14 марта '16 в 18:21 2016-03-14 18:21 atsakymas yra duotas Ved Prakash kovo 14 d., 16 val. 18:21 2016-03-14 18:21

Šiek tiek vėlai šventei,

Jei naudojate kampinį 7 (arba 5/6/7) ir PHP kaip API ir vis dar gaunate šią klaidą, pabandykite pridėti šiuos antraštės parametrus į galutinį tašką (PHP API).

  header("Access-Control-Allow-Origin: *"); header("Access-Control-Allow-Methods: PUT, GET, POST, PUT, OPTIONS, DELETE, PATCH"); header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization"); 

Pastaba : reikalingi tik „ Access-Control-Allow-Methods . Tačiau aš įdėjau dvi kitas „ Access-Control-Allow-Origin ir „ Access-Control-Allow-Headers , nes būtinai jas reikia įdiegti teisingai, kad kampinė programa tinkamai sąveikauja su jūsų API.

Tikiuosi, kad tai padės kam nors.

Sveikinimai.

0
24 янв. Anjana Silva atsakė sausio 24 d. 2019-01-24 18:44 '19 , 6:44 val. 2019-01-24 18:44

Visiškai aprašyta komentare pkozlowski. Turėjau darbo sprendimą su „AngularJS 1.2.6“ ir „ASP.NET Web Api“, bet kai atnaujinau „AngularJS“ į 1.3.3, užklausos nepavyko.

  • „Web Api“ serverio sprendimas turėjo papildyti OPTIONS užklausų apdorojimą konfigūravimo metodo pradžioje (daugiau šiame dienoraščio įraše ):

     app.Use(async (context, next) => { IOwinRequest req = context.Request; IOwinResponse res = context.Response; if (req.Path.StartsWithSegments(new PathString("/Token"))) { var origin = req.Headers.Get("Origin"); if (!string.IsNullOrEmpty(origin)) { res.Headers.Set("Access-Control-Allow-Origin", origin); } if (req.Method == "OPTIONS") { res.StatusCode = 200; res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Methods", "GET", "POST"); res.Headers.AppendCommaSeparatedValues("Access-Control-Allow-Headers", "authorization", "content-type"); return; } } await next(); }); 
0
27 февр. Jiří Kavulák atsakymas 27 vasario mėn 2015-02-27 11:38 '15, 11:38 am 2015-02-27 11:38

Jei naudojate API REST API, galite tai padaryti toliau.

Jums nereikia keisti žiniatinklio paslaugų įgyvendinimo.

Aš paaiškinsiu Jersey 2.x

1) Pirmiausia pridėkite „ResponseFilter“, kaip parodyta žemiau.

 import java.io.IOException; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; public class CorsResponseFilter implements ContainerResponseFilter { @Override public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { responseContext.getHeaders().add("Access-Control-Allow-Origin","*"); responseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT"); } } 

2), tada web.xml jersey servlet skelbime pridėkite žemiau

  <init-param> <param-name>jersey.config.server.provider.classnames</param-name> <param-value>YOUR PACKAGE.CorsResponseFilter</param-value> </init-param> 
0
26 мая '15 в 9:29 2015-05-26 09:29 Atsakymas pateikiamas neaiškioms gegužės 26 d., 15 val. 9:29 2015-05-26 09:29

Aš atsisakiau bandyti išspręsti šią problemą.

Mano „IIS web.config“ jame buvo tinkami „ Access-Control-Allow-Methods “, eksperimentavau su konfigūracijos nustatymų pridėjimu prie mano kampinio kodo, bet po kelių valandų darbo, bandydamas „Chrome“ skambinti domeno „JSON“ žiniatinklio paslauga, atsisakiau nusivylęs .

Galų gale, pridėjau kvailą ASP.Net tvarkytojo tinklalapį, gavau jį skambinti JSON žiniatinklio paslaugai ir grąžinti rezultatus. Jis uždirbo 2 minutes.

Čia yra naudojamas kodas:

 public class LoadJSONData : IHttpHandler { public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; string URL = "......"; using (var client = new HttpClient()) { // New code: client.BaseAddress = new Uri(URL); client.DefaultRequestHeaders.Accept.Clear(); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Add("Authorization", "Basic AUTHORIZATION_STRING"); HttpResponseMessage response = client.GetAsync(URL).Result; if (response.IsSuccessStatusCode) { var content = response.Content.ReadAsStringAsync().Result; context.Response.Write("Success: " + content); } else { context.Response.Write(response.StatusCode + " : Message - " + response.ReasonPhrase); } } } public bool IsReusable { get { return false; } } } 

Ir mano kampiniame valdiklyje ...

 $http.get("/Handlers/LoadJSONData.ashx") .success(function (data) { .... }); 

Esu tikras, kad yra paprastesnis / bendresnis būdas tai padaryti, tačiau gyvenimas yra per trumpas ...

Jis dirbo man, ir dabar galiu tęsti įprastą darbą!

0
11 нояб. Atsakymą pateikė Mike Gledhill lapkričio 11 d 2015-11-11 15:42 '15 15:42 2015-11-11 15:42

IIS MVC 5 / kampinis CLI projektas (taip, gerai žinau, kad jūsų problema susijusi su kampiniu JS) su API, aš padariau:

web.config , esančiame <system.webServer> mazge

  <staticContent> <remove fileExtension=".woff2" /> <mimeMap fileExtension=".woff2" mimeType="font/woff2" /> </staticContent> <httpProtocol> <customHeaders> <clear /> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Headers" value="Content-Type, atv2" /> <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS"/> </customHeaders> </httpProtocol> 

Global.asax.cs

 protected void Application_BeginRequest() { if (Request.Headers.AllKeys.Contains("Origin", StringComparer.OrdinalIgnoreCase)  Request.HttpMethod == "OPTIONS") { Response.Flush(); Response.End(); } } 

Tai turėtų išspręsti tiek MVC, tiek ir WebAPI problemas, nepadarius visų kitų problemų. Tada aš sukūriau „HttpInterceptor“ kampiniame CLI projekte, kuris buvo automatiškai pridėtas prie atitinkamos antraštės informacijos. Tikiuosi, kad tai padės kažkas šioje situacijoje.

0
01 нояб. Atsakymas duotas Damon Drake 01 lapkričio. 2018-11-01 23:52 '18 at 11:52 pm 2018-11-01 23:52