2014-04-09 8 views
73

मैं जो अब एक मोबाइल वेबसाइट के लिए परिवर्तित किया जा रहा है एक PhoneGap एप्लिकेशन विकसित की थी छोड़ कैसे। सब कुछ एक छोटी सी गड़बड़ी के अलावा सुचारू रूप से काम करता है। मैं एक POST अनुरोध के माध्यम से एक निश्चित तृतीय पक्ष API का उपयोग करता हूं, जो ऐप में ठीक काम करता है, लेकिन मोबाइल वेबसाइट संस्करण में विफल रहता है।विकल्प AngularJS में preflight अनुरोध

करीब से देख (मैं ब्राउज़र वास्तव में लगता है कि) यह AngularJS की तरह लगता है के बाद पहली बार एक विकल्प अनुरोध भेज रहा है। मैंने आज सीओआरएस के बारे में बहुत कुछ सीखा, लेकिन मुझे यह पता लगाना प्रतीत नहीं होता कि इसे पूरी तरह अक्षम कैसे किया जाए। मुझे लगता है कि एपीआई (ताकि पक्ष में परिवर्तन असंभव है) करने के लिए पहुँच नहीं है, लेकिन किसी डोमेन मैं उनके लिए पर काम कर रहा हूँ जोड़ लिया है पहुंच-नियंत्रण-अनुमति दें-उत्पत्ति हैडर।

इस कोड के बारे में मैं बात कर रहा हूँ है:

 var request = { 
       language: 'fr', 
       barcodes: [ 
        { 
         barcode: 'somebarcode', 
         description: 'Description goes here' 
        } 
       ] 
      }; 
     } 
     var config = { 
      headers: { 
       'Cache-Control': 'no-cache', 
       'Content-Type': 'application/json' 
      } 
     }; 
     $http.post('http://somedomain.be/trackinginfo', request, config).success(function(data, status) { 
      callback(undefined, data); 
     }).error(function(data, status) { 
      var err = new Error('Error message'); 
      err.status = status; 
      callback(err); 
     }); 

मैं विकल्प का अनुरोध और सिर्फ वास्तविक पोस्ट अनुरोध को छोड़ कि भेजने से ब्राउज़र (या AngularJS) कैसे रोक सकते हैं? मैं AngularJS 1.2.0 का उपयोग कर रहा हूँ।

अग्रिम धन्यवाद।

उत्तर

80

preflight application/json की अपनी सामग्री प्रकार से चालू होने जा रहा है। इसे रोकने का सबसे आसान तरीका है सामग्री-प्रकार को अपने मामले में text/plain सेट करना। application/x-www-form-urlencoded & multipart/form-data सामग्री-प्रकार भी स्वीकार्य हैं, लेकिन आप निश्चित रूप से उचित रूप से आपके अनुरोध पेलोड फ़ॉर्मेट करने के लिए की आवश्यकता होगी।

आप अभी भी इस परिवर्तन करने के बाद एक preflight देख रहे हैं, तो कोणीय रूप में अच्छी तरह के अनुरोध के एक एक्स हेडर को जोड़े हो सकता है।

+9

यह सही उत्तर है - आपकी सामग्री-प्रकार और कैश-कंट्रोल हेडर प्रीफलाइट अनुरोध को ट्रिगर कर रहे हैं। एक सादा सामग्री/प्रकार के पाठ/सादे के साथ प्राप्त करें और कुछ अन्य गैर-प्रीफलाइट किए गए अनुरोध को ट्रिगर करने का एकमात्र तरीका हैं। देखें: https: //developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS#Preflighted_requests –

+0

आह हाँ, कैश-कंट्रोल के बारे में भूल गया। –

+7

एक कस्टम हेडर प्रीफलाइट भी ट्रिगर करेगा। –

11

क्या रे ने कहा, आप इसे की तरह सामग्री हेडर संशोधित करके बंद कर सकते हैं के रूप में -

$http.defaults.headers.post["Content-Type"] = "text/plain"; 

उदाहरण के लिए -

angular.module('myApp').factory('User', ['$resource','$http', 
    function($resource,$http){ 
     $http.defaults.headers.post["Content-Type"] = "text/plain"; 
     return $resource(API_ENGINE_URL+'user/:userId', {}, { 
      query: {method:'GET', params:{userId:'users'}, isArray:true}, 
      getLoggedIn:{method:'GET'} 
     }); 
    }]); 

या सीधे एक कॉल करने के लिए -

var req = { 
method: 'POST', 
url: 'http://example.com', 
headers: { 
    'Content-Type': 'text/plain' 
}, 
data: { test: 'test' } 
} 

$http(req).then(function(){...}, function(){...}); 

यह कोई प्री-फ्लाइट विकल्प अनुरोध नहीं भेजेगा।

नोट: अनुरोध में कोई कस्टम हेडर पैरामीटर नहीं होना चाहिए, यदि अनुरोध हेडर में कोई कस्टम शीर्षलेख है तो ब्राउज़र प्री-फ्लाइट अनुरोध करेगा, आप इससे बच नहीं सकते हैं।

+1

मुझे इसे '$ http' के साथ कैसे करना चाहिए? – learnercys

+0

@learnercys अंतिम कोड (सीधे कॉल करने के लिए) की जांच करें? – Vivek

+0

धन्यवाद, यह वही है जो मैं कर रहा था। केवल 'परिवर्तन' विधि और एक अतिरिक्त शीर्षलेख 'प्राधिकरण' विधि ही परिवर्तन हैं। लेकिन अभी भी preflight भेज रहे हैं। – learnercys

1

कुछ प्रकार के क्रॉस-डोमेन AJAX अनुरोधों को निष्पादित करते समय, सीओआरएस का समर्थन करने वाले आधुनिक ब्राउज़र एक अतिरिक्त "प्रीफलाइट" अनुरोध डालेंगे यह निर्धारित करने के लिए कि क्या उन्हें कार्रवाई करने की अनुमति है या नहीं। उदाहरण क्वेरी से:

$http.get(‘https://example.com/api/v1/users/’ +userId, 
    {params:{ 
      apiKey:’34d1e55e4b02e56a67b0b66’ 
      } 
    } 
); 

इस टुकड़ा हम देख सकते हैं कि पता दो अनुरोध भेजा गया था (विकल्प और प्राप्त) के परिणामस्वरूप। सर्वर से प्रतिक्रिया में हेडर जो क्वेरी प्राप्त करने की अनुमति की पुष्टि करते हैं। यदि आपका सर्वर एक विकल्प अनुरोध को ठीक से संसाधित करने के लिए कॉन्फ़िगर नहीं किया गया है, तो ग्राहक अनुरोध विफल हो जाएंगे।

Access-Control-Allow-Credentials: true 
Access-Control-Allow-Headers: accept, origin, x-requested-with, content-type 
Access-Control-Allow-Methods: DELETE 
Access-Control-Allow-Methods: OPTIONS 
Access-Control-Allow-Methods: PUT 
Access-Control-Allow-Methods: GET 
Access-Control-Allow-Methods: POST 
Access-Control-Allow-Orgin: * 
Access-Control-Max-Age: 172800 
Allow: PUT 
Allow: OPTIONS 
Allow: POST 
Allow: DELETE 
Allow: GET 
-1

अपरिभाषित जावास्क्रिप्ट हैडर डेटा पास यह है के रूप में होगा, और डिफ़ॉल्ट कोणीय $ httpProvider हैडर विन्यास लेखन से अधिक करने के लिए सामग्री प्रकार की स्थापना: उदाहरण के लिए।Angular $http Documentation

$http({url:url,method:"POST", headers:{'Content-Type':undefined}).then(success,failure); 
2

मुझे लगता है कि सबसे अच्छा तरीका है जांच है अगर अनुरोध प्रकार का है "विकल्प" मध्य बर्तन से 200 वापस जाएँ। यह मेरे लिए काम किया।

express.use('*',(req,res,next) =>{ 
     if (req.method == "OPTIONS") { 
     res.status(200); 
     res.send(); 
     }else{ 
     next(); 
     } 
    }); 
-1

आप दो फाइलों में बदलने की जरूरत है। 1 - सबसे पहले ग्राहक की web.config फ़ाइल में system.webserver टैग के तहत टैग को जोड़ने के

<httpProtocol> 
     <customHeaders> 
      <add name="Access-Control-Allow-Origin" value="*"/> 
      <add name="Access-Control-Allow-Headers" value="Content-Type" /> 
      <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, 
      DELETE, OPTIONS" /> 
     </customHeaders> 
</httpProtocol> 

2 - सर्वर Global.asax फ़ाइल में

संरक्षित शून्य Application_BeginRequest() { अगर (Request.Headers.AllKeys.Contains ("उत्पत्ति") & & Request.HttpMethod == "विकल्प") { प्रतिक्रिया। फ्लश(); } }

संबंधित मुद्दे