আনুন: পোস্ট জসন ডেটা


559

আমি আনতে ব্যবহার করে একটি JSON অবজেক্ট পোস্ট করার চেষ্টা করছি ।

আমি যা বুঝতে পারি তা থেকে, আমাকে অনুরোধের শরীরে একটি স্ট্রিংফাইড জিনিস যুক্ত করতে হবে, যেমন:

fetch("/echo/json/",
{
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    method: "POST",
    body: JSON.stringify({a: 1, b: 2})
})
.then(function(res){ console.log(res) })
.catch(function(res){ console.log(res) })

জাসফিডেলের জসন প্রতিধ্বনি ব্যবহার করার সময় আমি প্রত্যাশা করেছি যে আমি যে বস্তুটি প্রেরণ করেছি (তা {a: 1, b: 2}) ফিরে পেয়েছি , তবে এটি ঘটে না - ক্রোম ডেভোলগুলি অনুরোধের অংশ হিসাবে জেএসএনকেও দেখায় না, যার অর্থ এটি প্রেরণ করা হচ্ছে না।


আপনি কোন ব্রাউজার ব্যবহার করছেন?
ক্রিজিসটফ সাফজানভস্কি

@ ক্রিজিসটফসফজানভস্কি ক্রোম ৪২, যার অর্থ পুরো আনার সমর্থন রয়েছে
রেজার

jsfiddle.net/abbpbah4/2 এই ফ্রিল্ডটি পরীক্ষা করুন আপনি কী ডেটা আশা করছেন? কারণ fiddle.jshell.net/echo/json এর অনুরোধটি খালি অবজেক্ট দেখাচ্ছে। {}
কৌশিক

প্রত্যাশিত আউটপুট পরিষ্কার করতে @ কৌশিককিশোর সম্পাদিত। res.json()ফিরে আসা উচিত {a: 1, b: 2}
রেজার

1
আপনি jsonযে সম্পত্তিটিতে যে ডেটা পাঠাতে চান তা অন্তর্ভুক্ত করতে ভুলে গিয়েছেন। তবে আমি bodyযেভাবেই হোক না কেন সঠিকভাবে আচরণ করা হচ্ছে না। এই স্নাতকটি দেখুন 5 সেকেন্ডের বিলম্ব এড়িয়ে যায়। jsfiddle.net/99arsnkg এছাড়াও, আপনি অতিরিক্ত শিরোনাম যুক্ত করার চেষ্টা করলে সেগুলি এড়ানো হবে। এটি সম্ভবত fetch()নিজেই একটি সমস্যা ।
বুমবক্স 16

উত্তর:


597

ES2017 async/awaitসমর্থন সহ , POSTএকটি JSON পেইড লোড করার পদ্ধতি এটি:

(async () => {
  const rawResponse = await fetch('https://httpbin.org/post', {
    method: 'POST',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({a: 1, b: 'Textual content'})
  });
  const content = await rawResponse.json();

  console.log(content);
})();

ES2017 ব্যবহার করতে পারবেন না? প্রতিশ্রুতি ব্যবহার করে @ ভিপি_আরটের উত্তর দেখুন

তবে প্রশ্নটি দীর্ঘদিন থেকে স্থির ক্রোম বাগের কারণে সৃষ্ট একটি সমস্যা জিজ্ঞাসা করছে
আসল উত্তর অনুসরণ।

ক্রোম ডেভলগুলিও অনুরোধের অংশ হিসাবে জেএসএনকে দেখায় না

এটি এখানে আসল সমস্যা , এবং এটি ক্রোম 46 এ স্থির করা ক্রোম ডেভলগুলি সহ একটি বাগ

এই কোডটি দুর্দান্ত কাজ করে - এটি JSON সঠিকভাবে পোস্ট করছে, এটি ঠিক দেখা যায় না।

আমি যে জিনিসটি প্রেরণ করেছি তা দেখতে প্রত্যাশা করব

এটি কাজ করছে না কারণ এটি জেএসফিডেলের প্রতিধ্বনির জন্য সঠিক বিন্যাস নয় ।

সঠিক কোড হল:

var payload = {
    a: 1,
    b: 2
};

var data = new FormData();
data.append( "json", JSON.stringify( payload ) );

fetch("/echo/json/",
{
    method: "POST",
    body: data
})
.then(function(res){ return res.json(); })
.then(function(data){ alert( JSON.stringify( data ) ) })

জেএসএন পে-লোড গ্রহণ করার জন্য শেষ পয়েন্টগুলির জন্য, মূল কোডটি সঠিক


15
রেকর্ডের জন্য, এটি একটি জেএসএন পে-লোড পোস্ট করছে না - এটি একটি ফর্ম পোস্ট ( x-www-form-urlencoded) নামের ক্ষেত্রের একটি জেএসওএন ডেটা সহ json। সুতরাং ডেটা দ্বিগুণ এনকোড করা হয়। একটি পরিষ্কার JSON পোস্টের জন্য, নীচে নীচে @vp_arth দ্বারা উত্তর দেখুন।
mindplay.dk

1
@ mindplay.dk এটি কোনও এক্স-www-form-urlencoded পোস্ট নয়। আনার এপিআই সর্বদা ফর্মডাটা অবজেক্টগুলিতে মাল্টিপার্ট / ফর্ম-ডেটা এনকোডিং ব্যবহার করে।
JukkaP

@ জুলকাপি আমি সংশোধন করছি। আমার মূল বিষয়টি ছিল ডাবল এনকোডিংয়ের সমস্যা।
mindplay.dk

2
সামগ্রী-প্রকার এখনও টেক্সট / এইচটিএমএল; চরসেট = আইসো -8859-1 জানি না আমি কী ভুল করছি ...
কেটি ওয়ার্কস

3
নিরাপদ দিকে থাকতে, res.okপ্রতিক্রিয়া কোডটি কোনও ধরণের ত্রুটি হলে নিশ্চিত হওয়া ভাল । .catch()শেষে একটি ধারা থাকা ভাল হবে । আমি বুঝতে পারি এটি কেবল একটি নমুনা স্নিপেট, তবে বাস্তব বিশ্বের ব্যবহারের জন্য এই বিষয়গুলি মনে রাখবেন।
কেন লিয়ন

206

আমি মনে করি আপনার সমস্যাটি কেবলমাত্র অনুরোধের jsfiddleপ্রক্রিয়া করতে পারে form-urlencoded

তবে জসন অনুরোধ করার সঠিক উপায় jsonএকটি দেহ হিসাবে সঠিক পাস :

fetch('https://httpbin.org/post', {
  method: 'post',
  headers: {
    'Accept': 'application/json, text/plain, */*',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({a: 7, str: 'Some string: &=&'})
}).then(res=>res.json())
  .then(res => console.log(res));


6
এটি সঠিক সমাধান, পিরিয়ড - অন্য প্রত্যেকে x-www-form-urlencodedবনাম সম্পর্কে মিশ্রিত বলে মনে হচ্ছে application/json, হয় সেগুলিতে মেলে না or
mindplay.dk

তবে এটি jsfiddle জন্য কাজ করে না। সুতরাং, আমি নিশ্চিত নই যে আপনি কেন "এটি সঠিক সমাধান, সময়কাল" বলবেন তা আমি বুঝতে পেরেছি। অন্য সবাই /echoকী জেফফুলের রুটের এপিআই সন্তুষ্ট করতে মোড়কটি করছে না ?
অ্যাডাম-বেইক

69

অনুসন্ধান ইঞ্জিনগুলি থেকে, আমি আনার সাথে নন-জসন ডেটা পোস্ট করার জন্য এই বিষয়টিতে শেষ করেছি, তাই ভেবেছিলাম আমি এটি যুক্ত করব।

জন্য অ JSON আপনি কি ফর্মটি ডেটা ব্যবহারের জন্য হবে না। আপনি কেবল একটি Content-Typeহেডারে সেট করতে পারেন application/x-www-form-urlencodedএবং একটি স্ট্রিং ব্যবহার করতে পারেন:

fetch('url here', {
    method: 'POST',
    headers: {'Content-Type':'application/x-www-form-urlencoded'}, // this line is important, if this content-type is not set it wont work
    body: 'foo=bar&blah=1'
});

সেই bodyস্ট্রিংটি তৈরির বিকল্প উপায় , তারপরে এটি টাইপ করে যেমনটি আমি উপরে করেছি, তা হল লাইব্রেরি ব্যবহার করা। উদাহরণস্বরূপ বা প্যাকেজ stringifyথেকে ফাংশন । সুতরাং এটি ব্যবহার করে এটির মতো দেখতে লাগবে:query-stringqs

import queryString from 'query-string'; // import the queryString class

fetch('url here', {
    method: 'POST',
    headers: {'Content-Type':'application/x-www-form-urlencoded'}, // this line is important, if this content-type is not set it wont work
    body: queryString.stringify({for:'bar', blah:1}) //use the stringify object of the queryString class
});

2
ক্যোয়ারী স্ট্রিংয়ের জন্য আপনাকে অনেক ধন্যবাদ, আমি JSON.stringify এর সাথে অনেকবার চেষ্টা করেছি কিন্তু আজাক্স প্রতিক্রিয়া ফিরিয়ে আনছে না। তবে ক্যোয়ারী স্ট্রিংটি কৌশলটি করেছে। আমি আরও দেখতে পেলাম যে এটি আনার কারণে স্ট্রিং তৈরির পরিবর্তে বডি প্যারামের জন্য জসন তৈরি করা হয়।
ড্যানিশ

1
আপনি মানুষ ধন্যবাদ! এটি সেরা জবাব! আমি গতকাল আমার সার্ভারে ওয়েব অ্যাপ্লিকেশন থেকে ফর্ম ডেটা সহ 'বডি' প্রেরণের কোনও উপায় অনুসন্ধান করার জন্য কয়েক ঘন্টা ধরে দেয়ালে আঘাত করছিলাম ... একটি পরামর্শ: pm n pm ইনস্টল কর্স - সেভ থেকে মুক্তি পাওয়ার জন্য এটি প্রয়োজন মোড: আনার
আলেকজান্ডার চেরেডনিকেনকো

ধন্যবাদ @ আলেকজান্ডারচেরেডনিকেনকো! এবং সেই কর্স নোটটি ভাগ করে নেওয়ার জন্য ধন্যবাদ যা আমি জানতাম না এমন একটি আকর্ষণীয় বিষয়। :)
Noitidart

1
আমার হৃদয়ের গভীর থেকে ধন্যবাদ আপনি আমার সময় এবং আমার জীবনও দু'বার
বাঁচিয়েছেন

1
থাঙ্কস @ বাফসার!
Noitidart

42

কিছু সময় ব্যয় করার পরে, বিপরীত প্রকৌশল জেএসফিডাল, পে-লোড উত্পন্ন করার চেষ্টা করছে - এর একটি প্রভাব রয়েছে।

return response.json();প্রতিক্রিয়া নয় এমন লাইনে চোখের যত্ন (যত্ন) নিন - এটি প্রতিশ্রুতি।

var json = {
    json: JSON.stringify({
        a: 1,
        b: 2
    }),
    delay: 3
};

fetch('/echo/json/', {
    method: 'post',
    headers: {
        'Accept': 'application/json, text/plain, */*',
        'Content-Type': 'application/json'
    },
    body: 'json=' + encodeURIComponent(JSON.stringify(json.json)) + '&delay=' + json.delay
})
.then(function (response) {
    return response.json();
})
.then(function (result) {
    alert(result);
})
.catch (function (error) {
    console.log('Request failed', error);
});

জেএসফিডাল: http://jsfiddle.net/egxt6cpz/46/ && ফায়ারফক্স> 39 এবং ক্রোম> 42


'x-www-form-urlencodedপরিবর্তে কেন application/json? পার্থক্য কি?
জুয়ান পিকাদো

@ জুয়ানপিকাডো - 2 বছর আগে জিসফিডাল বিপরীত প্রকৌশল পরে এটি কেবলমাত্র একটি বিকল্প ছিল যা এটি কাজ করতে পারে। অবশ্যই application/jsonসঠিক ফর্ম এবং এটি এখন কাজ করে। ভাল চোখের জন্য ধন্যবাদ:)
ক্রিজিসটফ সাফজানভস্কি

yw। কৌতূহল বিশদ, এটি আমার পরিবর্তে পুরানো উপায়ে fetch( stackoverflow.com/questions/41984893/… ) এর সাথে কাজ করে application/json। সম্ভবত আপনি কেন জানেন ...
হুয়ান পিকাদো

6
Content-Typeহয় application/json, কিন্তু আপনার আসল bodyপ্রদর্শিত হয় হতে x-www-form-urlencoded- আমি মনে করি না এই কাজ করা উচিত না? যদি এটি কাজ করে তবে আপনার সার্ভারটি অবশ্যই ক্ষমাশীল। নীচে @vp_arth এর উত্তরটি সঠিক বলে মনে হচ্ছে।
mindplay.dk

18

আপনি যদি খাঁটি জেসন আরএসটি এপিআই ব্যবহার করে থাকেন তবে আমি অনেক উন্নতি নিয়ে আনার () চারদিকে একটি পাতলা মোড়ক তৈরি করেছি:

// Small library to improve on fetch() usage
const api = function(method, url, data, headers = {}){
  return fetch(url, {
    method: method.toUpperCase(),
    body: JSON.stringify(data),  // send it as stringified json
    credentials: api.credentials,  // to keep the session on the request
    headers: Object.assign({}, api.headers, headers)  // extend the headers
  }).then(res => res.ok ? res.json() : Promise.reject(res));
};

// Defaults that can be globally overwritten
api.credentials = 'include';
api.headers = {
  'csrf-token': window.csrf || '',    // only if globally set, otherwise ignored
  'Accept': 'application/json',       // receive json
  'Content-Type': 'application/json'  // send json
};

// Convenient methods
['get', 'post', 'put', 'delete'].forEach(method => {
  api[method] = api.bind(null, method);
});

এটি ব্যবহার করতে আপনার কাছে ভেরিয়েবল apiএবং 4 টি পদ্ধতি রয়েছে:

api.get('/todo').then(all => { /* ... */ });

এবং একটি asyncফাংশন মধ্যে:

const all = await api.get('/todo');
// ...

JQuery সহ উদাহরণ:

$('.like').on('click', async e => {
  const id = 123;  // Get it however it is better suited

  await api.put(`/like/${id}`, { like: true });

  // Whatever:
  $(e.target).addClass('active dislike').removeClass('like');
});

আমি মনে করি আপনি একটি ভিন্ন সেট যুক্তি বোঝাতে চেয়েছিলেন Object.assign? হওয়া উচিত Object.assign({}, api.headers, headers)কারণ আপনি headersসাধারণের হ্যাশে কাস্টম যুক্ত রাখতে চান না api.headers। ঠিক আছে?
মোবিগিতল

@ মোবিজিটাল পুরোপুরি ঠিক, আমি তখন সেই উপদ্রব সম্পর্কে জানতাম না তবে এখন এটিই আমার একমাত্র উপায়
ফ্রান্সিসকো প্রেসেনেসিয়া

11

এটি সম্পর্কিত Content-Type। আপনি যেমন অন্যান্য আলোচনা এবং এই প্রশ্নের উত্তর থেকে লক্ষ্য করেছেন যে কিছু লোক সেট করে এটি সমাধান করতে সক্ষম হয়েছিল Content-Type: 'application/json'। দুর্ভাগ্যক্রমে আমার ক্ষেত্রে এটি কাজ করে না, আমার পোষ্ট অনুরোধটি এখনও সার্ভারের পাশে খালি ছিল।

তবে আপনি যদি jQuery এর সাথে চেষ্টা করে থাকেন $.post()এবং এটি কাজ করে তবে কারণটি সম্ভবত jQuery এর Content-Type: 'x-www-form-urlencoded'পরিবর্তে ব্যবহার করার কারণে application/json

data = Object.keys(data).map(key => encodeURIComponent(key) + '=' + encodeURIComponent(data[key])).join('&')
fetch('/api/', {
    method: 'post', 
    credentials: "include", 
    body: data, 
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})

1
আমার ব্যাকএন্ড ডে পিএইচপি দিয়ে API তৈরি করেছে, আশা করেছিল যে ডেটা কোয়েরি স্ট্রিংয়ের মতো হবে, কোনও জসন অবজেক্ট নয়। এটি সার্ভার সাইডে খালি প্রতিক্রিয়া সমাধান করেছে।
eবললেস্ট

11

একই সমস্যা bodyছিল - কোনও ক্লায়েন্টের কাছ থেকে কোনও সার্ভারে পাঠানো হয়নি ।

যোগ করা হচ্ছে Content-Typeহেডার আমার জন্য এটি মীমাংসিত:

var headers = new Headers();

headers.append('Accept', 'application/json'); // This one is enough for GET requests
headers.append('Content-Type', 'application/json'); // This one sends body

return fetch('/some/endpoint', {
    method: 'POST',
    mode: 'same-origin',
    credentials: 'include',
    redirect: 'follow',
    headers: headers,
    body: JSON.stringify({
        name: 'John',
        surname: 'Doe'
    }),
}).then(resp => {
    ...
}).catch(err => {
   ...
})

7

শীর্ষস্থানীয় উত্তর পিএইচপি 7 এর জন্য কাজ করে না, কারণ এতে ভুল এনকোডিং রয়েছে, তবে আমি অন্যান্য উত্তরগুলির সাথে সঠিক এনকোডিংটি বুঝতে পারি। এই কোডটি প্রমাণীকরণ কুকিজ প্রেরণ করে, যা আপনি সম্ভবত যেমন পিএইচপি ফোরামগুলির সাথে ডিল করার সময় চান:

julia = function(juliacode) {
    fetch('julia.php', {
        method: "POST",
        credentials: "include", // send cookies
        headers: {
            'Accept': 'application/json, text/plain, */*',
            //'Content-Type': 'application/json'
            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" // otherwise $_POST is empty
        },
        body: "juliacode=" + encodeURIComponent(juliacode)
    })
    .then(function(response) {
        return response.json(); // .text();
    })
    .then(function(myJson) {
        console.log(myJson);
    });
}

3

কারও পক্ষে এটি কার্যকর হতে পারে:

আমার সমস্যাটি ছিল যে আমার অনুরোধের জন্য ফর্মডাটা প্রেরণ করা হচ্ছে না

আমার ক্ষেত্রে এটি নিম্নলিখিত শিরোনামগুলির সংমিশ্রণ যা সমস্যা এবং ভুল সামগ্রী-প্রকারের কারণও তৈরি করেছিল।

সুতরাং আমি অনুরোধের সাথে এই দুটি শিরোলেখ পাঠাচ্ছিলাম এবং যখন আমি কাজ করা শিরোনামগুলি সরিয়েছিলাম তখন ফর্মডাতাটি প্রেরণ করা হয়নি।

"X-Prototype-Version" : "1.6.1",
"X-Requested-With" : "XMLHttpRequest"

এছাড়াও অন্যান্য উত্তরগুলির মতামত হিসাবে কনটেন্ট-টাইপ শিরোনামটি সঠিক হওয়া দরকার।

আমার অনুরোধের জন্য সঠিক কন্টেন্ট-টাইপ শিরোনামটি ছিল:

"সামগ্রী-প্রকার": "অ্যাপ্লিকেশন / x-www-form-urlencoded; চরসেট = ইউটিএফ -8"

সুতরাং নীচের লাইনটি যদি আপনার ফর্মডেটা অনুরোধের সাথে সংযুক্ত না হয় তবে সম্ভবত এটি আপনার শিরোনাম হতে পারে। আপনার শিরোনামকে ন্যূনতমতে আনার চেষ্টা করুন এবং তারপরে আপনার সমস্যার সমাধান হয়েছে কিনা তা দেখার জন্য তাদের একে একে যুক্ত করার চেষ্টা করুন।


3

আমি মনে করি যে, আমাদের JSON অবজেক্টটিকে স্ট্রিংয়ে পার্স করার দরকার নেই, যদি রিমোট সার্ভারটি তাদের অনুরোধের মধ্যে জসনকে গ্রহণ করে, তবে চালান:

const request = await fetch ('/echo/json', {
  headers: {
    'Content-type': 'application/json'
  },
  method: 'POST',
  body: { a: 1, b: 2 }
});

যেমন কার্ল অনুরোধ

curl -v -X POST -H 'Content-Type: application/json' -d '@data.json' '/echo/json'

দূরবর্তী অঞ্চলে কোনও জসন ফাইলটিকে দেহ হিসাবে গ্রহণ না করার জন্য কেবল একটি ডেটা ফর্ম পাঠান:

const data =  new FormData ();
data.append ('a', 1);
data.append ('b', 2);

const request = await fetch ('/echo/form', {
  headers: {
    'Content-type': 'application/x-www-form-urlencoded'
  },
  method: 'POST',
  body: data
});

যেমন কার্ল অনুরোধ

curl -v -X POST -H 'Content-type: application/x-www-form-urlencoded' -d '@data.txt' '/echo/form'

2
এটি স্পষ্টতই ভুল। আপনার জসনকে আপনার স্ট্রালিফাই করা দরকার কিনা তা সার্ভারের সাথে কিছু করার নেই। আপনার curlআদেশটি নিখুঁতভাবে এটি করছে! আপনি যদি আপনার বস্তুগুলিকে এটি হিসাবে পাস করার আগে আরও শক্তিশালী না করেন তবে bodyআপনি কেবল "[object Object]"আপনার অনুরোধের অংশ হিসাবে প্রেরণ করবেন । দেব সরঞ্জামগুলিতে একটি সাধারণ পরীক্ষা আপনাকে এটি দেখায়। এটি খুলুন এবং এই ট্যাবটি না রেখেই চেষ্টা করুন:a = new FormData(); a.append("foo","bar"); fetch("/foo/bar", { method: 'POST', body: {}, headers: { 'Content-type': 'application/json' } })
অলিগোফ্রেন

2

যদি আপনার জেএসএন পে-লোডে অ্যারে এবং নেস্টেড অবজেক্ট থাকে তবে আমি URLSearchParams এবং jQuery এর param()পদ্ধতিটি ব্যবহার করব ।

fetch('/somewhere', {
  method: 'POST',
  body: new URLSearchParams($.param(payload))
})

আপনার সার্ভারে, এটি কোনও মানক এইচটিএমএল এড <form>হওয়ার মতো দেখবে POST

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.