запыт пасля Jquery перапыніла: толькі палова паштовых параметраў прыбываюць

У мяне ёсць заўважыў дзіўнае з'ява ў маёй лямпы асяроддзі.
За фронтэнда я выконваю запыт пасля AJAX з JQuery, як гэта:

$.post('save.php', {data1: d1, data2: d2, [...],  dataN: dN})

Пераменны d1 у дна збірае з вэба-сайта (напрыклад, з тэкставых уваходаў, пракручваць, сцяжкоў і г.д.) з jQuery загадзя.

Файл save.php Бярэцца параметры data1 у DataN і захоўвае іх у базе дадзеных у адным запыце.

Запыт займае каля 500 мс і працуе без праблем , калі мяняю старонак (напрыклад, пстрыкнуўшы спасылку) падчас запыту.

Як правіла, я б чакаць, што запыт павінен быць перапынены і ігнаруецца (што было б добра) , але (і гэта дзіўныя паводзіны) запыт, здаецца, завершана, але толькі частка перадаюцца дадзеных і, такім чынам, захаваныя.

Гэта азначае, што, напрыклад, сцэнар PHP захоўвае толькі data1 у дадзеныя 5 і наборы data6 у DataN апаражніць.
Праблема, як уяўляецца, выклікана просьбай AJAX ужо (не скрыпт), так палёў $ _ POST [ 'data6'] у $ _ POST [ 'DataN'] не зьяўляюцца ўсталяваць у PHP ў гэтым сцэнары.

So my questions:
Why does this happen (is this expected behaviour)?
How can I avoid it?

Update
The problem is neither jQuery nor PHP solely. jQuery collects the values correctly and tries to post them to php. I just validated it - it works. The PHP script on the other hand handles everything it gets as expected - it just does not receive the whole request.
So the problem must be the interrupted request itself. Unlike I'd expect it does not abort or fail, it still transmits all the data until the cut off.
Then PHP gets this post data and starts handling it - obviously missing some information.

Update 2
I fixed the problem by adding a parameter eof after dataN and checking if it was set in php. This way I can be sure the whole request was transmitted.
Nevertheless this does not fix the source of the problem which I still don't understand.
Any help anyone?

25
Гэта ўсяго толькі адзін XHR і гэта, як вы размяшчае некалькі параметраў: api.jquery.com/jQuery.post </а>
дададзена аўтар Horen, крыніца
@ Stef77 Вось што я зрабіў, каб высветліць прычыну: 1) З console.log() і выхадам Firebug I паштовымі параметрамі прама перад запытам - яны былі ў камплекце 2) у PHP Я паслаў ліст з var_dump ўсяго $ параметры _POST - яны былі няпоўнымі, як паказана ў маім пытанні. Так што толькі першыя некалькі паштовых параметраў прыбытку, часам значэнне аднаго параметра нават перапыненыя ў сярэдзіне.
дададзена аўтар Horen, крыніца
@Wallack Гэта тое, што я раблю, каб вырашыць гэтую праблему (гл Update 2 у маім пытанні). Аднак я не ведаю, крыніца праблемы яшчэ
дададзена аўтар Horen, крыніца
Я ведаю, што jQuery збірае ўсе дадзеныя правільна і jQuery адпраўляе запыт AJAX. І я ведаю, што ў PHP толькі частка яго паступае. Такім чынам, праблема, здаецца, сам перарваны запыт.
дададзена аўтар Horen, крыніца
@mguimard Так, прабачце за бязладдзе
дададзена аўтар Horen, крыніца
Вы можаце ўбачыць <�б> Wireshark , якія дадзеныя былі адпраўленыя на сервер
дададзена аўтар Dor, крыніца
Я не думаю, што перапыненне загрузкі старонкі на навігатар можа паўплываць на боку сервера скрыпт такім чынам. Перадача дадзеных POST гэта самае першае, што адбываецца, таму я не веру, што частковыя дадзеныя могуць быць адпраўленыя. Нават калі б гэта было так, я мяркую, што сервер заўважыць запыт з'яўляецца няпоўным, і нават не запусціць скрыпт. Нешта яшчэ павінна быць тут адбываецца. Вы станоўчы чаканы дадзеныя сапраўды пасланы навігатар (праверце адладчык JS на вашым навігатары)?
дададзена аўтар RandomSeed, крыніца
@mguimard Гэта было б правільны адказ, калі запіс у базе дадзеных не была атамарна. Аднак ОП гаворыцца, што параметры «захоўваюцца ў адным запыце».
дададзена аўтар RandomSeed, крыніца
Каб адказаць на ваша пытанне аб тым, як пазбегнуць гэтага, проста праверыць, калі Исеть ($ _POST [ «DataN»]) вяртае ісціну.
дададзена аўтар Jerska, крыніца
На спасылцы націсніце каб паспрабаваць адмяніць усе тыя, што засталіся запыты XHR, як апісана тут: stackoverflow.com/a/7566169/550618 Калі гэта вырашае праблема гэта будзе першым крокам да вырашэння.
дададзена аўтар regilero, крыніца
Проста даў яму іншую думку. Гэта павінна быць практычна немагчыма, што сервер прымае POST няпоўнага. Калі гэта можа адбыцца, усе віды гадасцяў б сутыкнуліся з легіёнам кодэраў. Firebug мае ўкладку «Сетка», дзе вы можаце ўбачыць POST і яго загалоўкі, калі вы не хочаце, каб нюхаць трафік. Я мяркую, што ёсць загаловак «Content-Length» адпраўляюцца з просьбай з разумнай коштам? Які сервер вы карыстаецеся? Стандартны Apache? Вы трайная праверылі, што гэта адзін і толькі POST адпраўляецца, або ІНШЫ jQuery POST робіцца ПАСЛЯ перайсці на іншую старонку?
дададзена аўтар stef77, крыніца
Калі ласка, звярніце ўвагу на адказ я прапанаваў.
дададзена аўтар stef77, крыніца
@Horen ОК, так што здаецца, што Ajax пост у jQuery нырае адрэзаць, калі вы пяройдзеце на іншую старонку, і гэта адрэзаны дадзеныя адпраўляюцца на сервер ... Не ведаю, як сервер выяўляе КАНЕЦ POST, але ў адпаведнасці з гэтым : stackoverflow.com/questions/ 12600199/& hellip; ці гэта: stackoverflow.com/questions/4824451/… такі эфект наўрад ці варта здарыцца ... сеткавай панюхаць, каб адлюстраваць загалоўкі і адпраўленыя дадзеныя ўсё яшчэ могуць дапамагчы. Ці здараецца гэта, калі вы карыстаецеся іншы браўзэр, таксама? Не маглі б вы апублікаваць прыклад дадзеных, вы пасылаеце?
дададзена аўтар stef77, крыніца
@Horen На жаль, каб спытаць, але, як вы ведаеце, што jQuery адпраўляе поўныя дадзеныя? Што я рабіць далей (калі вы не зрабілі гэта раней) сапраўды да ТСРйитра (г.зн. нюхаць) прычым дадзеныя <�б> Адпраўленыя ад вашага кліента, і дадзеных, што <�б> ПРЫБЫЎ на вашым серверы. <�Б> IF jQuery сапраўды дроселі на «перапыненага запыту», вы б пабачылі, што толькі частка дадзеных перадаецца ў першую чаргу. Тым не менш, я чакаю, што дадзеныя адпраўляюцца сапраўды гэтак жа, як паступае на сервер, але ТСРйитр будзе сказаць напэўна. Тады вы ведаеце, па меншай меры, на боку сервера выдатна, і вы можаце засяродзіцца на кліенце.
дададзена аўтар stef77, крыніца
Для ўдакладнення: Вы кажаце, што ёсць выпадкі (напрыклад, калі вы «змена старонка»), калі вы бачыце ў вашым браўзэры, што Ajax запыт запаўняецца з усімі дадзенымі, і гэта дакладны запыт паступае толькі часткова на сэрвэры? Ці гэта можа быць і так, што, калі вы «змены старонак», якія (па любой прычыне) не ўсе дадзеныя запаўняюцца, але адхапілі і адпраўляюцца на сервер няпоўнага? Я WIRESHARK трафік адпраўляецца на сервер, каб пераканацца, што там на самой справе, на самай справе ёсць розніца паміж тым, што перадаецца ад кліента і тое, што запаўняецца ў РНР $ _POST, якія я знаходжу цяжка паверыць.
дададзена аўтар stef77, крыніца
Sniff сеткі на сэрвэры, каб убачыць, якія дадзеныя дасягае яго.
дададзена аўтар Carlos Campderrós, крыніца
Ніколі не бачыў jQuery пост з data1 [...], DataN .. у якасці параметраў. Ці ёсць некалькі XHR, ці толькі адзін XHR?
дададзена аўтар mguimard, крыніца
@YaK сапраўды, трэба нешта пойдзе не так у іншым месцы. Я знайшоў гэтую спасылку, можа быць, гэта можа дапамагчы PHP скрыпт, перш за ўсё пасля атрымання дадзеных»> stackoverflow.com/questions/3945683/…
дададзена аўтар mguimard, крыніца
Гэта чаканае паводзіны, калі ваш вэб-кліент адмяніць запыт, ваш PHP струмень не быў забіты, няма адкату на запыты, якія вы зрабілі, перш чым забіць. См php.net/manual/en/function.ignore-user-abort .php ігнараваць карыстальнік перапыняе.
дададзена аўтар mguimard, крыніца
ОК, вы толькі адрэдагавалі і загорнутыя Вашие дадзеныя паміж {}
дададзена аўтар mguimard, крыніца
У мяне дакладна такая ж праблема. памер POST каля 650Kb, і будзе пашкоджаны, калі акно закрыцця браўзэра або асвяжальнай старонка ў выпадку Аякса да пасля завяршэння. ajax.success() не звольняць, але частковыя дадзеныя размешчаны на «save.php» 200 ОК-статус. Firebug/хром Сеткавы адладчык не рэгіструе запыт HTTP, але Апач робіць яго часопіс, з частковым лічыльніку байтаў. Гэта павінна быць памылка ў Apache/PHP.
дададзена аўтар sivann, крыніца
Ці можаце вы паказаць PHP апрацоўкі на AJAX-запыт кода? Хутчэй за ўсё, код апрацоўвае дадзеныя няправільна.
дададзена аўтар MarcDefiant, крыніца
Вы ўпэўненыя ў сваім jQuery сінтаксісу $ .post?
дададзена аўтар netvision73, крыніца
А як наконт параметру, паказвальнага алею колькасці параметраў за? у гэтым выпадку вы маглі б зрабіць адкат ці нешта падобнае, калі ёсць адзін або некалькі Тытулы адсутнічаюць.
дададзена аўтар Wallack, крыніца

13 адказы

Паспрабуйце выканаць наступныя дзеянні для ліквідацыі праблем:

  1. Праверка post_max_size ў налады PHP і параўнаць яго з памерам дадзеных, вы публікуеце.

  2. Карыстальнік HTTP запыт будаўніком, гэта значыць выкарыстанне Скрыпач , каб зрабіць запыт HTTP і праверыць, што ён вяртаецца.

  3. Выкарыстоўвайце print_r ($ _ POST); на верхняй частцы save.php , каб праверыць, што вы атрымліваеце ў ім

    <./li>
  4. Выкарыстоўвайце інструмент, як Firebug , каб праверыць, што jQuery выклала.

  5. Акрамя таго, варта праверыць аб'ект JSON на баку кліента, што вы адпраўляеце. г.зн. JSON.stringify (some_object); </р>

  6. <�Літый> <�р> Паспрабуйце размясціць некаторыя асноўныя дадзеныя выбаркі { "data1": 1, "data2": 2, "Data3": 3, "Data4": 4, "дадзеныя 5": 5, "data6": 6} </р>

Хутчэй за ўсё, вы адпраўляеце шмат дадзеных або верагодныя дадзеных несапраўднае!

Edits: Very Foolish act but lets say you posted count as well. so directly check isset($_POST['data'.$_POST['count']] )

5
дададзена
1. post_max_size не праблема. Запыт заўсёды працуе, за выключэннем, калі перарываецца, 3. save.php вяртае толькі першую частку параметраў. Ёсць параметры адсутнічаюць дакладна, 4. Допісы jQuery поўныя дадзеныя, так што ўсе параметры
дададзена аўтар Horen, крыніца
@ Stef77 ён можа пасылаць велізарныя дадзеныя дазваляе казаць 1Мбы або больш jQuery паста зойме трохі часу для загрузкі, але сярэдняе значэнне ў той час як код не будзе выконвацца, і я лічу, $ _POST або быць запоўненыя дадзенымі або даволі пустым масівам. Гэтае пытанне не мае сэнсу ў тым, што тэрміны!
дададзена аўтар Waqar Alamgir, крыніца
Не маглі б вы ўдакладніць, што вы маеце на ўвазе з «перарывацца»? Ці з'яўляецца гэта 100% ўзнаўляльнасць паводзіны, калі вы выклікаеце ваш Аякс POST, а затым націсніце іншую спасылку, а затым, калі адбываецца «палова дадзеных» з'ява? Заўсёды? Гэта гучыць даволі немагчыма, бо запыт Ajax будзе даволі хутка, так што павінна быць выпадкі, калі ён працуе, нават калі вы спынілі. І сервер не хвалюе, што вы робіце на канец кліента - альбо ён атрымлівае POST, які будзе поўным, паколькі jQuery не будзе спрацоўваць запыт, перш чым ён не атрымаў усе дадзеныя, ці ён не атрымлівае POST наогул. Глядзіце іншы мой каментар => Wireshark, ТСРйитр.
дададзена аўтар stef77, крыніца
@WaqarAlamgir Я таксама цяжка паверыць, што POST толькі «напалову заселены», я ніколі не бачыў такога (што не азначае, што гэта можа быць, вядома). Зваротная сувязь аб тым, што здарылася пры спробе вашага пункту нумар 6 можа быць цікава. І, магчыма, ёсць памылка выкінуты з запыту Ajax JQuery? => jQuery Ajax пасля памылкі пры навігацыі ад старонкі "> stackoverflow.com/questions/9229005/…
дададзена аўтар stef77, крыніца

Вы можаце праверыць значэнне Content-Length загаловак быць атрымаў у PHP.

Гэта значэнне павінен было разлічана на бок кліента пры выкананні запыту POST. Калі ён не супадае, гэта ваша памылка, то і там. І гэта ўсё дыягностыкі вам трэба - калі Content-Length не адпавядае дадзеных POST, адмаўляюць POST несапраўднымі; няма неабходнасці дадатковых параметраў (вылічэнні даўжыні дадзеных POST можа быць клопатаў, хоць). Акрамя таго, вы можаце высветліць, чаму ж PHP, у той час як <�ет> дэкадаванне POST і, такім чынам, быць у стане праверыць яго даўжыню, тым не менш, здаецца, прымае няправільную даўжыню (магчыма, інфармацыя, неабходная для выяўлення памылкі дзесьці сярод кнопка $ _ SERVER зменных?).

If it does match though, and still data isn't arriving (i.e., the Content-Length is smaller, and correctly describes the cut-off POST), then it is proof that the POST was inspected after the cut-off, and therefore either the error is in the browser (or, unlikely, in jQuery) or there is something between the browser and the server (a proxy?) that is receiving an incomplete query (with Content-Length > Actual length) and is incorrectly rewriting it, making it appear "correct" to the server, instead of rejecting it out of hand.

Некаторыя выпрабаванні як тэорыі і абыходны шлях

Рэзюмэ: Я атрымаў былы няправільна, але той, мабыць, маеце рацыю. Гл ніжэй код для ўзору, які працуе на маёй тэставай сістэме (Linux OpenSuSE 12.3, Apache).

Я лічыў, што запыт з няправільным кодам <> Content-Length будзе адмоўлена з 400 Bad Request . Я быў неправы. Здаецца, што, прынамсі, мой Apache з'яўляецца шмат больш мяккім.

Я выкарыстаў гэты просты PHP код для доступу ключавых пераменных, якія ўяўляюць цікавасць для мяне

<?php
    $f = file_get_contents("php://input");
    print $_SERVER['CONTENT_LENGTH'];
    print "\nLen: " . strlen($f) . "\n";
?>

а затым я падрыхтаваў запыт з няправільным кодам <> Content-Length адправіць яго, выкарыстоўваючы Nc :

POST /p.php HTTP/1.0
Host: localhost
Content-Length: 666

answer=42

...and lo and behold, nc localhost 80 < request yields no 400 error:

HTTP/1.1 200 OK
Date: Fri, 14 Jun 2013 20:56:07 GMT
Server: Apache/2.2.22 (Linux/SUSE)
X-Powered-By: PHP/5.3.17
Vary: Accept-Encoding
Content-Length: 12
Content-Type: text/html

666
Len: 10

Мне прыйшло ў галаву тое, што даўжыня змесціва можа таксама быць зрушаная на адзін ці два ў выпадку, калі запыт завяршыўся зварот карэткі, і што зварот карэткі - LF? CRLF?. Аднак, калі я дадаў просты HTML, каб мець магчымасць адпраўляць яго ў браўзэры

<form method="post" action="?"><input type="text" name="key" /><input type="submit" value="go" /></form>

Я быў у стане праверыць, што ў Firefox (апошні), IE8, Chrome (апошні), усё працуе на XP Pro SP3, <�моцны> значэнне Content-Length гэта тое ж самае, StrLen з PHP://ўвод .

За выключэннем выпадкаў, калі запыт адрэзаны, то ёсць.

Адзіная праблема заключаецца ў тым, што PHP://ўвод не заўсёды даступны нават для POST дадзеных.

Гэта пакідае нас яшчэ ў цяжкім становішчы:

IF THE ERROR IS AT THE NETWORK LEVEL, i.e., the POST is prepared and supplied with a correct Content-Length, but the interruption makes it so that the whole data is cut off as this comment by Horen seems to indicate:

<�Р> Такім чынам, толькі першая пара паштовых параметраў прыбытку, часам <�моцны> значэнне аднаго параметра нават перапынена ў сярэдзіне

затым сапраўды праверкі Content-Length перашкодзіць PHP ад апрацоўкі няпоўнага запыту:

<?php
    if ('POST' == $_SERVER['SERVER_PROTOCOL'])
    {
            if (!isset($_SERVER['Content-Length']))
            {
                header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request', True, 400);
                die();
            }
            if (strlen(file_get_contents('php://input'))!=(int)($_SERVER['Content-Length']))
            {
                header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request', True, 400);
                die();
            }
    }
   //... go on
?>

ON THE OTHER HAND if the problem is in jQuery, i.e. somehow the interruption prevents jQuery from assembling the full POST, and yet the POST is made up, the Content-Length calculated of the incomplete data, and the packet sent off -- then my workaround can't possibly work, and the "telltale" extra field must be used, or... perhaps the .post function in jQuery might be extended to include a CRC field?

4
дададзена
Вы можаце адкрыць новае пытанне з падрабязным апісаннем вашай канкрэтнай сітуацыі. Я быў бы рады бачыць, ці можам мы што-небудзь прыдумаем. Толькі, я павінен быў бы вярнуцца да вас на працягу дня або каля таго.
дададзена аўтар LSerni, крыніца
@ Stef77, я лічу, што большасць браўзэраў (я зараз эксперыментую з Firefox) ёсць буфер каля 16-32 кілабайта паміж целам POST і разеткай. Калі цела POST знаходзіцца ніжэй гэтага мяжы, яно альбо адпраўлена ці не дасланы. Няма неабходнасці, каб праверыць што-небудзь. Акрамя таго, кароткія цела маюць мала верагоднасці атрымаць яго ў шыю ад змены старонкі. Вельмі вялікія цела, хоць, знаходзяцца пад пагрозай; але яны вельмі рэдкія сітуацыі, і гэта тлумачыць, чаму ніхто не здаецца, каб праверыць гэта. Найбольш проста <�я> ня трэба .
дададзена аўтар LSerni, крыніца
Я думаю, што нават калі загаловак Content-Length адрозніваецца ад фактычнага памеру POST дадзеных, гэта было б вельмі рэдкае стан. Толькі падумайце, я ніколі ніколі не бачыў чэкі, як вы вывесілі апошні робіцца. Калі б яны былі неабходныя, большасць сайтаў з выкарыстаннем паведамленняў для PHP проста не будуць працаваць. Акрамя таго, што адбудзецца, калі вы адпраўляеце Content-Length <�б> менш , чым фактычныя дадзеныя? Акрамя таго, апошні каментар Hören тут stackoverflow.com/a/17086985/2406389 мяркуе, што няма дадзеных, якія размешчаны на ўсіх. Не маючы зірнуць на фактычныя крыніцы JQuery, я баюся, што мы вельмі шмат страцілі ў здагадках.
дададзена аўтар stef77, крыніца
Я магу пацвердзіць, што вы напісалі, наш Apache (2.2.3 на CentOS 5.9) таксама адказвае 200 OK . Акрамя таго, калі дадаць Content-Type: прымяненне/х-WWW-формаў-urlencoded на запыт, я магу var_dump $ _ POST [ 'адказ'] (без дадатковага загалоўку гэта не падобна на працу), а на самай справе, калі Content-Length гэта <�б> 8 , $ _POST [ 'адказ'] з'яўляецца <�б> 4 , а не 42 . У той час як я хацеў бы таксама чакаць 400 Bad Request , я да гэтага часу сумняваюся, што вы павінны праверыць Content-Length і PHP://ўвод ўручную , Што мы павінны ведаць, з'яўляецца Content-Length загаловак jQuery пасля Hören адпраўляе на сервер.
дададзена аўтар stef77, крыніца
@Iserni Але кароткая і вялікая адносныя; думаць толькі пра павольны сеткавых злучэннях, асабліва калі справа даходзіць да сотавых тэлефонаў. Эфект быў бы, што мабільныя карыстальнікі адчуваюць адрэзаныя паведамлення часцей, чым карыстачы з рэгулярнай сеткай. Цяжка паверыць. Рашэнне будзе тое, што вы заўсёды павінны выканаць санітарныя праверкі, як той, які вы не прадугледжана, незалежна ад таго, наколькі малы аб'ём дадзеных вы перадаеце, таму што вы ніколі не мог быць упэўнены. Можа быць, вядома, зламаная версія jQuery або асаблівыя абставіны Хорн звернутую тут.
дададзена аўтар stef77, крыніца
на жаль, змест даўжыня ў маім выпадку супадае з карумпаванай даўжынёй дадзеных, не ў поўнай меры.
дададзена аўтар sivann, крыніца

Я думаю, што мы можам выключыць праблемы на сайце сервера (калі гэта не нейкія экзатычныя або самастойна створаны сервер-дэман), таму што ніхто ніколі не пасылае «канец-дадзеных» -параметров з HTTP POST запыт пераканайцеся, што ўсе дадзеныя сапраўды адпраўленыя. Гэта апрацоўваецца HTTP сам (глядзі, напрыклад, Detect канец HTTP цела запыту ). Больш за тое, я не думаю, што вы павінны праверыць Content-Length загаловак пры POST ING дадзеных на вашым серверы, проста з-за таго, што ніхто не робіць гэта, калі-небудзь , Па меншай меры, не ў зусім звычайных умовах, як вы апісалі іх (адпраўка Ajax POST праз jQuery ).

Таму я мяркую, што jQuery адпраўляе сінтаксічна правільны POST , але ён адрэзаны. Я думаю, што калі вы перапыніць збор дадзеных шляхам пераходу на іншую старонку, jQuery Фармуе Ajax запытаць з дадзеных, якія ён быў у стане сабраць і адпраўляе сінтаксічна правільны POST на сервер, але з абрэзанымі дадзенымі.

Так як вы карыстаецеся Firebug , калі ласка, перайдзіце на яго ўкладку сеткі і актываваць ўпарціцца , таму дадзеныя трафіка не губляюцца пры пераходзе на іншую старонку. Затым выклікаць ваш Ajax POST , перайдзіце на іншую старонку (і, такім чынам, «перапыненне» клавішы Ajax выклік) і праверце ў Firebug 's чыстую ўкладку, што дадзеныя фактычна былі накіраваны на сервер, адкрыўшы ALL клавішы POST <�код /> запыты і праверкі загалоўкі ўкладка (і ўнутры гэтага, запыт загалоўкі <�код /> ўкладка).

Я думаю, што адна з двух рэчаў можа адбыцца:

  1. Вы ўбачыце, што дадзеныя, адпраўленыя на сервер адрэзаны ўжо ў загалоўках ўяўляюцца вам у Firebugсеткі ўкладцы і Змест -длина правільна разлічваецца ў адпаведнасці з фактычнай (адрэзаны) даўжыня POST дадзеных. У адваротным выпадку, я ўпэўнены, што сервер будзе адхіляць запыт як Bad Request ў цэлым.
  2. Вы ўбачыце, што існуе мноства POST запыты, некаторыя з іх (магчыма, з поўным, ня адразаюць дадзеных) фактычна перарываецца, і таму ніколі не дасягаюць сервера, але, па меншай меры, адзін <�код > POST запыт (зноў жа, з абрэзанымі дадзенымі), што IST запускаецца нейкай іншай механізм у вашым Javascript , гэта значыць не трыгер вы думалі, але перайсці на іншую старонку, усё больш і іншай Ajax запыты можа быць выклікана (толькі здагадка, так як я не ведаю, зыходны код).

У любым выпадку, я думаю, вы выявіце, што гэтая праблема IST звязаная з кліентам і серверам проста апрацоўвае (няпоўныя, але (у тэрмінах HTTP ) сінтаксічна сапраўднымі) дадзеных кліента, дасланых да яго.

З гэтага моманту, вы можаце адладжваць Javascript і рэалізаваць нейкі механізм, які прадухіляе адпраўку няпоўных дадзеных на сервер. Зноў жа, гэта цяжка сказаць, што рабіць менавіта так як я не ведаю, астатнюю частку зыходнага кода, але, можа быць, ёсць нейкая цяжкая дзеянне адбываецца ў зборы дадзеных, і вы маглі б пераканацца, што POST адбываецца толькі тады, калі ўсе дадзеныя сапраўды збіраюцца. Ці, магчыма, вы маглі б прадухіліць навігацыю, пакуль запыт Ajax не будзе завершаны або такімі рэчаў.

Што можа быць цікава, калі ўсё гэта не мае сэнсу, будзе мець погляд на больш зыходнага кода, асабліва, як Ajax POST спрацоўвае, і калі ёсць якія-небудзь іншыя падзеі і напрыклад, калі вы пяройдзеце на іншую старонку. Ўзор дадзеных вы адпраўляеце таксама можа быць цікава.

EDIT: Я хацеў бы таксама адзначыць, што вывад дадзеных з console.log() можа ўвесці ў зман, бо гэта не гарантавана, што гэта дадзеныя фактычна пасланыя, гэта проста лаглинь які вылічаецца ў дадзенай прадукцыі на дакладны час, калі console.log() называецца. Вось чаму я прапанаваў нюхаць сеткавага трафіку, таму што тады (і толькі тады), вы можаце быць упэўнены, што <�моцны> сапраўды пасылаецца (і атрымаў). Тым не менш, гэта крыху больш складана, калі вы не прывыклі да яго (і немагчыма, калі вы карыстаецеся зашыфраванага трафіку, напрыклад, з дапамогай HTTPS ), так што Firebug сетка ўкладка можа быць добрым кампрамісам.

4
дададзена

I have tried to recreate this problem using triggers, manually, changing server settings, doing my very best to #$%& things up, using different data sizes but I never ever got only half a request in PHP. Simply because apache will not invoke PHP untill the request is completely done. See this question about Reading “chunked” POST data in PHP

Так што адзінае, што можа пайсці не так, што jQuery толькі збірае частка дадзеных, а затым робіць запыт POST. Выкарыстоўваючы толькі $. Пост ( 'save.php', дадзеныя) , як вы згадалі, што не здарыцца. Яго альбо працуюць, каб сабраць дадзеныя або яго чаканне адказу ад сервера.

Пры пераключэнні сайтаў падчас збору, існуе звычай быць запыт. І калі вы перамыкаецца пасля запыту было зроблена, і вы адысці хутка, перш, чым было перададзена ўсе дадзеныя, сервер Apache будзе бачыць яго як палова запыту, а таксама не спасылацца на PHP.

Некаторыя прапановы:

Ці магчыма, што вы карыстаецеся паасобныя старонкі для частковых і паспяховых запытаў? Паколькі PHP робіць толькі дадаць першыя 1000 элементаў у _ POST і, магчыма, няўдалыя запыты маюць больш data1000 = дадзеных элементаў $? Такім чынам, існуе звычай быць EOF пароў.

Ці магчыма, што вы збіраеце дадзеныя ў глабальнай зменнай у JavaScript і ёсць метад onbeforeunload, які пасылае дадзеныя, а? Таму што тады можа быць толькі палова дадзеных у POST.

Ці можаце вы падзяліцца інфармацыяй пра дадзеныя, якія вы seding? Ёсць шмат дробных элементаў (напрыклад, data1 да data10000) або некалькі вялікіх раз?

Ці заўсёды гэта той жа элемент, які вы атрымалі ў апошні раз? Як заўсёды data6, як вы згадваеце? Таму што, калі ён ёсць, шанцы няўдалай спробы заўсёды на тое ж поле DataN будуць вельмі тонкімі.

3
дададзена
у маім выпадку гэта толькі ідзе не так, калі адзін з параметраў дадзеных вельмі доўгая (100kb, напрыклад)
дададзена аўтар Horen, крыніца
@ Stef77 Ўкладка сеткі не дае шмат інфармацыі. Ён кажа, што запыт быў перапынены і выводзіць запыт на Ajax паста ў чырвоным колеры.
дададзена аўтар Horen, крыніца
@Horen добра, так што няма ніякіх дадзеных, якія перадаюцца на сервер: getfirebug.com/wiki/ index.php/Net_Panel # Request_List Як я сказаў у маім адказе: ці ёсць некалькі пошт, ці толькі што сінгл, чырвоныя адзін? Што такі стан HTTP? Адменена? 400 Няправільны запыт? Ах, і ў выпадку, калі вы не бачыце: вы можаце перамыкаць адкрыты запыт, націснуўшы на абразок плюс злева ад запыту.
дададзена аўтар stef77, крыніца
@Horen Калі ласка, праверце ўкладку сетку ў Firebug, як я прапанаваў у маёй абароне. Чым больш я думаю пра гэта, тым больш я перакананы, што гэта прывядзе вас да кораня праблемы.
дададзена аўтар stef77, крыніца

Post data looks just like GET:

Header1: somedata1\r\n
Header2: somedata2\r\n
...
HeaderN: somedataN\r\n
\r\n
data1=1&data2=2&...&dataN=N

Калі запыт перарываецца, у некаторых выпадках, апошняя радок можа быць перададзена толькі часткова. Такім чынам, вось некаторыя магчымыя рашэнні:

  1. Compare Content-Length and strlen($HTTP_RAW_POST_DATA)
  2. Validate input data
  3. Pass not so much data at one time
3
дададзена

Вы можаце праверыць свой часопіс хаста ў

<�Код>/вар/Часопіс/паведамленні

Апошні раз я быў «адсутнічаю» паштовая зменныя ў PHP я выявіў, што я адпраўляў пустыя ASCII сымбалі і сервер (CentOS) разглядае гэта напад, а затым апускаючы тыя канкрэтныя зменныя ... Узяў мяне тыдзень, каб зразумець гэта! Гэта быў адказ часопіса сервера:

suhosin[1173]: ALERT - ASCII-NUL chars not allowed within request variables - dropped variable 'data3' (attacker '192.168.0.37', file '/var/www/upload_reader.php')

Калі гэта ваша праблема, Tyr да, з JS, сціскаць зменныя, кадзіраваць іх з base64. Выкажыце іх з дапамогай AJAX, то атрымаць, то на PHP, decode64 затым разархіваваць! Гэта вырашыла для мяне;)

2
дададзена

Здагадка - функцыя Suhosin на сэрвэры Ubuntu/Debian выклікае поле адрэзаць?

1
дададзена

Перад тым як адправіць запыт, усталюйце «onbeforepageunload» апрацоўшчык дакумент (забараніць пераход на іншую старонку), і адвязаць пасля поспеху.

Да прыкладу:

$(document).on('unload', function(e){
    e.preventDefault();
   //Here you can display a message, you need to wait a bit
    return false;
});
1
дададзена
Вы шукаеце onbeforeunload замест: на ( «beforeunload», ...), але я не думаю, што гэта можа дапамагчы OP з яго выпуску
дададзена аўтар A. Wolff, крыніца

Для таго, каб знайсці наш больш аб тым, што адбываецца, чаму не правільна код, які вы AJAX запыт з дапамогай Ajax функцыі jQuery ст. Выкарыстоўвайце ўсе функцыі зваротнага выкліку для адсочвання таго, што здарылася з вашым званком або што вярнулася? Элемент тып усталяваны ў POST і элемент дадзеныя ажыццяўляе незалежна аб'ектную структуру {...} Вам падабаецца.

$.ajax({
    url : "save.php",
    type : "POST",
    data : {
        "ajax_call" : "SOME_CUSTOM_AJAX_REQUEST_REFERENCE",
        "data1" : data1,
        "data2" : data2,
        "data2" : data2,
        "dataN" : dataN
    },
    //dataType : "html", contentType: "text/html; charset=utf-8",
    dataType : "json", contentType: "application/json; charset=utf-8",
    beforeSend: function() {
        //alert('before send...');
    },
    dataFilter: function() {
        //alert('data filter...');
    },
    success: function(data, textStatus, jqXHR) {
        //alert('success...');
        var response = JSON.parse(jqXHR.responseText, true);
        if (undefined != response.data) {
            my_error_function();
        }
        my_response_function(response.data);
    },
    error: function(jqXHR, textStatus, errorThrown) {
        //alert('error...');            
    },
    complete: function (xhr, status) {
        //alert('end of call...');          
        my_continuation_function();
    }
});
1
дададзена
У той час як гэта магло б дапамагчы высветліць, што запыт быў перапынены ці не скончаны правільна, гэта не вырашыць праблему, РНР апрацоўкі няпоўных дадзеных і не перашкаджае корань праблемы і не тлумачыць яго.
дададзена аўтар Horen, крыніца

Мая праблема была там занадта шмат зменных у адным з маіх паштовых аб'ектаў. PHP мае max_input_vars зменную, якая ўсталёўваецца на 1000 па змаўчанні.

Я дадаў гэты радок у мой файл .htaccess (так як у мяне няма доступу да файла php.ini):

php_value max_input_vars 5000

Праблема вырашана!

1
дададзена
я была такая ж праблема, і гэта вырашыць яе :)
дададзена аўтар Niksac, крыніца

У мяне такая ж праблема. памер POST каля 650Kb, і будзе пашкоджаны, калі акно закрыцця браўзэра або асвяжальнай старонка ў выпадку Аякса да пасля завяршэння. ajax.success() не звольняць, але частковыя дадзеныя размешчаны на «save.php» 200 ОК-статус. Content-даўжыня $ _SERVER з'яўляецца не выкарыстоўваць як прапанавана elswhere, паколькі яна супадае з фактычным зместам даўжынёй няпоўных дадзеных.

Я зразумеў, 2 шляху пераадолення гэтага:

  1. , як вы прапануеце, дадаць паштовую зменную ў канцы. Здаецца, працуе, хоць гэта здаецца трохі рызыкоўным.
  2. зрабіць свой «save.php» сцэнар захавання ў часовай калонку дб, а затым выкарыстоўваць ajax.success (), каб выклікаць іншы скрыпт, скажа savefinal.php, без перадачы якіх-небудзь дадзеных, які перадае дадзеныя з калонкі тэмпу у апошні слупок (або проста сцягі гэта дадзеныя сапраўдных). Такім чынам, калі пост перарваныя дадзеныя будуць размяшчацца толькі на калонцы тэмпу ў базе дадзеных (ці не будуць пазначаныя як сапраўдныя).

.Success() не выклікаецца, калі пост перарываецца, так што гэта павінна працаваць.

Я мяркую, што гэта jQuery памылка адпраўкі няправільна (вельмі маленькі) кантэнту даўжыні да Apache, і Апач вымушаны выказаць здагадку, што запыт на запіс завершана, але я не зусім упэўнены.

0
дададзена

Вырашыў праблему шляхам павелічэння max_input_vars ў файле php.ini майго сервера

Так як у мяне было больш за 1000 зменных у масіве, толькі частка з іх была атрымана ад сервера!

Спадзяюся, што гэта дапамагае нехта!

0
дададзена

Чаму гэта адбываецца (гэта чаканае паводзіны)?

Была таксама шукаць прычыну гэтага дзіўнага паводзінаў, калі некаторыя зменныя з пасады адсутнічалі і прыйшлі на гэтае пытанне, дзе тлумачыцца вельмі падобнае паводзіны <�моцны> з павольным падключэннем да вэб-кліенту, які паслаў запыт POST з шматгалосныя/формаў-дадзеных .

Тут ідзе згаданы пытанне:

<�Р> Я сутыкнуўся з праблемай, калі аддалены вэб-кліент з павольным злучэннем   не ўдаецца адправіць поўны запыт POST з шматчастковы/змесцівам формаў-дадзеных   але PHP да гэтага часу выкарыстоўваюць часткова атрыманыя дадзеныя для запаўнення масіва $ _POST.   У выніку адзін значэнне ў масіве $ _POST можа быць няпоўным і больш   значэння могуць адсутнічаць.

See How to check for incomplete POST request in PHP

Як я магу пазбегнуць гэтага?

Там вы можаце знайсці рэкамендуемае рашэнне, а таксама. Тым не менш, такое ж рашэнне ўжо было прапанавана вамі.

<�Р> Вы можаце дадаць поле <�тып = «утоены» імя уваходнага = "поўны"> (да прыкладу)   як <�моцны> апошні <�моцны /> параметр. у PHP праверыць, па-першае, ці быў гэты параметр   адпраўлена ад кліента. калі гэты параметр паслаў - вы можаце быць упэўнены, што вы   атрымаў усе дадзеныя.
0
дададзена