अपने छोटे से Javascript ऐप के लिए मैंने CGI के साथ सर्वरसाइड API फ़ंक्शन लिखा।

मैंने इसे बहुत सरल बना दिया है, और पूर्ण उदाहरण स्क्रिप्ट इस तरह दिखती है:

#!/usr/bin/env perl

use strict; use warnings; use 5.014; 

use CGI;
use JSON;
use Data::Dumper;

my $q = new CGI;
my %p = $q->Vars;

_api_response();

sub _api_response {
  my ( $error ) = @_;
  my $res;

  my $status = 200;
  my $type = 'application/json';
  my $charset = 'utf-8';

  if ( $error ) {
    $status = 500;
    $res->{data} = {
      status => 500,
    };
    $res->{error} = {
        error => 'failure',
        message => $error,
        detail => Dumper \%p,
    };
  } else {
    $res->{data} = {
      status => 200,
    };
  }

  print $q->header( 
    -status   => $status, 
    -type     => $type,
    -charset  => $charset,
  );

  my $body = encode_json( $res );
  print $body;
}

जब मैं इसे JS स्क्रिप्ट से fetch के साथ कॉल करता हूं, तो इसे कोई प्रतिक्रिया निकाय नहीं मिलता है। अगर मैंने डेवलपर्स टूल्स/नेटवर्क से चेक किया है, तो इसका कोई प्रतिक्रिया निकाय भी नहीं है। अगर मैं ब्राउज़र में एक ही यूआरएल दर्ज करता हूं, तो यह JSON बॉडी दिखाता है। अगर मैं curl का उपयोग करता हूं

curl -v 'https://example.com/my_api?api=1;test=2;id=32'

प्रतिक्रिया लगता है भी सही शरीर है:

< HTTP/2 200 
< date: Mon, 13 Sep 2021 14:04:42 GMT
< server: Apache/2.4.25 (Debian)
< set-cookie: example=80b7b276.5cbe0f250c6c7; path=/; expires=Thu, 08-Sep-22 14:04:42 GMT
< cache-control: max-age=0, no-store
< content-type: application/json; charset=utf-8
< 
* Connection #0 to host example.com left intact
{"data":{"status":200}}

fetch इसे एक शरीर के रूप में क्यों नहीं देखता है?

पूर्णता के लिए, मैं जेएस भाग भी शामिल करता हूं:

async function saveData(url = '', data = {}) {
  const response = await fetch(url, {
    method: 'GET', 
    mode: 'no-cors', 
    cache: 'no-cache', 
    credentials: 'omit',
    headers: {
      'Content-Type': 'application/json'
    },
    redirect: 'follow', 
    referrerPolicy: 'no-referrer', 
  });
  console.log(response); // body is null
  return response.json(); 
}

फ़ंक्शन का उपयोग इस प्रकार करना:

saveData('https://example.com/my_api?api=1;test=2;id=32', { answer: 42 })
  .then(data => {
    console.log(data);
  })
  .catch( error => {
    console.error( error );
  });

कंसोल पर मुझे त्रुटि दिखाई देती है:

SyntaxError: Unexpected end of input

इस त्रुटि का एक संभावित कारण खाली JSON स्ट्रिंग है।

5
w.k 13 सितंबर 2021, 17:18

3 जवाब

सबसे बढ़िया उत्तर

मैं आपकी समस्या को पुन: उत्पन्न करने में सक्षम था, और फिर मैं इसे ठीक करने में सक्षम था।

यह एक CORS मुद्दा था। आपको CORS को आगे और पीछे दोनों तरफ सक्षम करना होगा।

सामने के छोर पर आपको अपने पृष्ठ के <head> में मेटा टैग के साथ सामग्री सुरक्षा नीति सेट करनी होगी:

<meta http-equiv="Content-Security-Policy" content="default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval' http://localhost">

(localhost को अपने वास्तविक डोमेन में बदलना न भूलें।)

पीठ पर आपको सीओआरएस हेडर जोड़ने की जरूरत है:

  print $q->header( 
    -status   => $status, 
    -type     => $type,
    -charset  => $charset,
    -access_control_allow_origin => '*', # <-- add this line
  );

एक साइड नोट के रूप में, आप जिन सेटिंग्स में जा रहे हैं उनमें से कोई भी fetch आवश्यक नहीं है। और चूंकि आप प्रतिक्रिया की प्रतीक्षा कर रहे हैं और फिर वैसे भी एक और वादा वापस कर रहे हैं, इसके लिए वास्तव में कोई एसिंक फ़ंक्शन होने का कोई कारण नहीं है।

जब तक आप अप्रयुक्त data तर्क के साथ कुछ करने के लिए तैयार नहीं होते, तब तक निम्नलिखित कोड पर्याप्त होगा:

function saveData(url = '', data = {}) {
    return fetch(url).then(response=>response.json()); 
}
3
I wrestled a bear once. 20 सितंबर 2021, 23:41

आपको response.json() के लिए भी await करना होगा।

return response.json(); के बजाय return await response.json(); आज़माएं

1
ernix 14 सितंबर 2021, 15:05

अर्धविराम अब कुछ संदर्भों में पैरामीटर विभाजक के रूप में स्वीकार नहीं किया जाता है, जो असंगत व्यवहार की व्याख्या कर सकता है। एम्परसेंड के साथ प्रयास करें:

saveData('https://example.com/my_api?api=1&test=2&id=32', { answer: 42 })
  .then(data => {
    console.log(data);
  })
  .catch( error => {
    console.error( error );
});
0
vqf 17 सितंबर 2021, 16:37