Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: JavaScript: Miten korjata ongelma NS_BINDING_ABORTED?

Sivun loppuun

walkout_ [14.05.2023 10:26:55]

#

Miten korjata ongelma NS_BINDING_ABORTED?

Ilman tätä ChatGPT:n vastausta?

NS_BINDING_ABORTED is a JavaScript error that occurs when a web page attempts to make an AJAX (Asynchronous JavaScript and XML) request, but the request is interrupted or aborted before it can be completed. This can happen for a variety of reasons, such as the user navigating away from the page or a network error.

To disable NS_BINDING_ABORTED errors in Firefox, you can do the following:

- Type "about:config" in the address bar and press Enter.
- Click "I accept the risk!" to proceed.
- Search for "network.http.response.timeout" in the search bar.
- Double-click the "network.http.response.timeout" preference to edit it.
- Change the value to a higher number, such as 120.
- Click "OK" to save the preference.

Increasing the network response timeout should reduce the likelihood of NS_BINDING_ABORTED errors, but it may also cause requests to take longer to complete. Additionally, it's important to note that this error is often caused by issues outside of the user's control, so disabling the error message may not necessarily resolve the underlying issue.

Lebe80 [15.05.2023 13:30:35]

#

Mikä tämän postauksen pointti nyt oli? Että olet löytänyt ChatGPT:n?

walkout_ [15.05.2023 16:03:11]

#

Lebe80 kirjoitti:

Mikä tämän postauksen pointti nyt oli? Että olet löytänyt ChatGPT:n?

Nope... vaan ei ChatGPT osaa auttaa... pitä taas värvätä ammattilainen korjaaman bugit Laravel-back-endillä ja ReactJS-front-endillä.

Metabolix [15.05.2023 22:03:40]

#

Jospa aloittaisit ihan perusteista eli tutkisit, missä kohti koodia ja minkälaisessa tilanteessa virhe tapahtuu jne. Tai sitten ainoa vaihtoehto taitaa todellakin olla ammattilaisen palkkaaminen.

Lebe80 [16.05.2023 09:27:30]

#

walkout_ kirjoitti:

Lebe80 kirjoitti:

Mikä tämän postauksen pointti nyt oli? Että olet löytänyt ChatGPT:n?

Nope... vaan ei ChatGPT osaa auttaa... pitä taas värvätä ammattilainen korjaaman bugit Laravel-back-endillä ja ReactJS-front-endillä.

:O


[pretends-to-be-surprised.gif]

walkout_ [21.05.2023 03:32:07]

#

Metabolix kirjoitti:

Jospa aloittaisit ihan perusteista eli tutkisit, missä kohti koodia ja minkälaisessa tilanteessa virhe tapahtuu jne. Tai sitten ainoa vaihtoehto taitaa todellakin olla ammattilaisen palkkaaminen.

ChatGPT:n viimeisin vastaus on siihen että tutkinut olen nyt vikaa.
1) Kaikki toimii moittetta minun paikallisen koneen XAMPP-asennuksessa
2) Mutta ei toimi minun Virtuaalipalvelimella

Joten ChatGPT sanoi, että vika voi olla minun palvelimen CPU:ssa joka on vain 12-ytiminen ja muistia on vain 32 Gt josta jälellä enää 5 Gt, koska palvelimella on useita J2EE-sovelluksia, joissa oma sisään rekenettu Tomcat/Jetty. Ja palvelimella on todellavaltava trafiikki niin palvelimen kapsiteetti ei riitä enää siihen, ettei NS_BINDING_ABORTED-virhttä tulisi.

Käski optimoimaan koodini Back-endillä ja Front-endillä ja jos en itse osaa niin käski palkkaamaan ammattilaisen joka osaa.

Ongelma on se nyt että olen kuluttunat jo yli 2000 € erään koodarin palkkioihin Upworkistä koko sovellukseni tekemiseen niiltä osin mitä en itse osaa tehdä ja virhe on joko hänen tekosiaan tai minun tekisia, koska muuttelen hänen koodia sitten paljon mielekkäämmäksi omasta mielestäni ja tehnyt lisää toimintoja jotka hänen työn jälkeen osaan kyllä tehdä. Ja nyt on rahat ihan finaalissa, enkä tiedä milloin saan rahaa lisää maksaa ks. koodarille tämän vian korjaamisesta.

noutti [27.05.2023 21:02:19]

#

Jos laitat vaikka coodia näkyviin, niin voisit päästä hieman halvemmalla. Tosin jos bäkärin infra huutaa punaisella, niin ei sitä muutamalla rivillä korjata

walkout_ [03.06.2023 09:19:48]

#

noutti kirjoitti:

Jos laitat vaikka coodia näkyviin, niin voisit päästä hieman halvemmalla. Tosin jos bäkärin infra huutaa punaisella, niin ei sitä muutamalla rivillä korjata

Jaa mites laitan koodia näkyviin kuin pistämällä minun GIT-repon, jossa koodi on julkiseksi?

Päivitin nyt VPS:n 16-ytimiseen prossuun ja 64 Gt RAM:iin, jne. Eikä tämä korjaa vikaa.

walkout_ [03.06.2023 09:32:44]

#

No back-end koodi on tässä:

public function myprofileSave(Request $request){

        $auth = Auth::user();

        $user = User::where(['id' => $auth->id])->first();
        $gender = User::where(['gender' => $auth->id])->first();
        $profile_picture_is_null = User::where(['profile_picture_path' => $auth->id])->first();
        $file = $request->file('file');

        if($file){

            $filename = uniqid() . '.' . $file->getClientOriginalExtension();

            try {
                if($user->profile_picture_path){
                    Storage::delete($user->profile_picture_path);
                }
            } catch (\Throwable $th) {
                //throw $th;
            }

            $path = $file->storeAs('public/uploads', $filename);
            // get the dimensions of the original image
            $original_image = storage_path().'/app/'.$path;
            list($width, $height) = getimagesize($original_image);

            // calculate the new dimensions
            $new_width = 400;
            $new_height = 400;

            // create a new image with the new dimensions
            $new_image = imagecreatetruecolor($new_width, $new_height);

            // copy and resize the image data from the original image into the new image
            $sourceImage = imagecreatefromjpeg($original_image);
            imagecopyresampled($new_image, $sourceImage, 0, 0, 0, 0, $new_width, $new_height, $width, $height);

            // output the new image as a JPEG file
            imagejpeg($new_image, storage_path().'/app/'.$path);
            $user->profile_picture_path = $path;
        }
        $user->name = $request->input('fullname');
        $user->gender = $request->get('gender');

        $user->save();

        if ($profile_picture_is_null==null && !str_starts_with($user->profile_picture_path, 'public')) {
            if ($request->get('gender') == "male") {
                $profilepicture = "default-male";
            } else {
                $profilepicture = "default-female";
            }
            //$user->profile_picture_path = null;
        } else {
            $user->profile_picture_path = Storage::url($user->profile_picture_path);
            $profilepicture = "custom";
        }

        return response()->json([
            'success' => true,
            'profilepicture' => $profilepicture,
            'user'=> $user
        ], 200);
    }

Ja front-end tässä:

import React, { useState, useCallback, useEffect, useRef } from "react";
import { withRouter } from "react-router-dom";
import { Formik, Field, Form, ErrorMessage, useField } from "formik";
import * as Yup from "yup";
import Axios from "axios";
import Cropper from "./../ImageCropper/ImageCropper";
import { getCroppedImg } from "./../ImageCropper/cropImage";
import { API_BASE_URL, ACCESS_TOKEN_NAME } from "../../constants/apiConstants";
import request from "../../utils/Request";
import TextInput from "./../common/TextInput";
import { AuthContext } from "../../contexts/auth.contexts";
import "./MyProfile.css";
import LOADING from "../../1487-loading.gif";
import DefaultMaleImage from "../../male-default-profile-picture.png";
import DefaultFemaleImage from "../../female-default-profile-picture.png";
import ImageCropper from "./../ImageCropper/ImageCropper";

function MyProfile(props) {
  const [data, setData] = useState(null);
  const { authState, authActions } = React.useContext(AuthContext);
  const [crop, setCrop] = useState({ x: 0, y: 0 });
  const [zoom, setZoom] = useState(1);
  const [croppedArea, setCroppedArea] = useState(null);
  const [croppedImageFile, setCroppedImageFile] = useState('a');
  const [imageSrc, setImageSrc] = useState(null);
  const profileRef = useRef();
  const [showCropper, setShowCropper] = useState(false);
  const [showMessage, setShowMessage] = useState(null);

  const onCropChange = useCallback((cropTemp) => {
    setCrop(cropTemp);
  }, []);

  const onFileChange = (event) => {
    if (event.target.files && event.target.files.length > 0) {
      const fileReader = new FileReader();
      fileReader.readAsDataURL(event.target.files[0]);
      fileReader.onload = () => {
        setImageSrc(fileReader.result);
        setShowCropper(true);
      };
    }
  };

  const onCropComplete = useCallback((croppedArea) => {
    if(croppedArea){
      console.log(croppedArea);
      setCroppedArea(croppedArea);
    }
  }, []);

  const onZoomChange = useCallback((zoom) => {
    setZoom(zoom);
  }, []);

  useEffect(() => {
    request()
      .get(API_BASE_URL + "/api/users/userdata", {
        headers: {
          Authorization: "Bearer " + localStorage.getItem(ACCESS_TOKEN_NAME),
        },
      })
      .then((res) => {
        setData(res.data);

      });
  }, []);


  const SignupSchema = Yup.object().shape({
    name: Yup.string().required("Name is required"),
    gender: Yup.string().required("Gender is required"),
  });

  const handleSubmit = async (values, formProps) => {
    const formData = new FormData();
    if(croppedImageFile){
      formData.append('file', croppedImageFile );
    }
    formData.append('fullname', values.name);
    formData.append('gender', values.gender);
    formProps.setSubmitting(true);

    request()
      .post(API_BASE_URL + "/api/manage/myprofile", formData)
      .then((res) => {
        console.log(formProps);
        // setIsSubmitting(false);
        debugger
        formProps.setSubmitting(false)
        if(res.status === 200){
          if(res.data.success === true ){
            setData(res.data.user);
            setShowMessage(res.data.message)
            setTimeout(()=>{
              setShowMessage(null)
            },2500)
          }
        }
      }).catch((err)=>{
        console.log('aa');
        debugger
      });
  }

  function CustomTextInput(props) {
    const [field, meta] = useField(props);
    return (
      <div>
        <label htmlFor={props.name}>{props.label}</label>
        <input {...field} {...props} />
        {meta.touched && meta.error ? (
          <div className="error">{meta.error}</div>
        ) : null}
      </div>
    );
  }

  if (!data) {
    return <div className="loading-screen"><img src={LOADING} alt="Loading..." /></div>;
  }

  var defaultImage;

  if (data.gender=="male") {
    defaultImage = DefaultMaleImage;
  } else {
    defaultImage = DefaultFemaleImage;
  }

  return (
    <div className="mt-2">
        {showMessage && <div className="alert alert-success" >{showMessage}</div>}
        <h3 className="my-2">My Details</h3>
        {!imageSrc && <img className="max-height-profile-pic" src={data.profile_picture_path?(API_BASE_URL + data.profile_picture_path):defaultImage} />}
        <br />
        {imageSrc && (
            <ImageCropper
              imageSrc={imageSrc}
              crop={crop}
              zoom={zoom}
              aspect={1}
              showCropper={showCropper}
              setShowCropper={setShowCropper}
              onCropChange={onCropChange}
              onCropComplete={onCropComplete}
              onZoomChange={onZoomChange}
              setCroppedImageFile={setCroppedImageFile}
              cropShape="round"
            />
        )}
        {!imageSrc && <button className="btn btn-info " onClick={()=>{
          profileRef.current.click();
        }} > Upload Image </button>}
        {imageSrc && <button className="btn btn-danger " onClick={()=>{
          setImageSrc(null)
        }} > Remove Image </button>}
        {imageSrc && <button className="btn btn-info mx-2 " onClick={()=>{
          setShowCropper(true)
        }} > Crop Image </button>}
      <input className="btn btn-primary" style={{display: "none"}} type="file" ref={profileRef} onChange={onFileChange} />
      <br />
      <br />
      <div className="userForm">
        <Formik
          initialValues={{
            name: data.name,
            gender: data.gender,
          }}
          validationSchema={SignupSchema}
          onSubmit={(values, formProps) => {
            handleSubmit(values, formProps);
          }}
        >
          {({ submitForm, isSubmitting }) => (
            <Form className="row g-3">
              <div className="col-12">
                <CustomTextInput
                  label="Fullname"
                  name="name"
                  type="text"
                  className="form-control"
                />
              </div>
              <div className="col-12">
                <label for="gender" className="select-gender-label-myprofile">
                  Gender
                </label>
                <br />
                <Field className="select-gender-myprofile" as="select" name="gender">
                  <option value="male">Male</option>
                  <option value="female">Female</option>
                </Field>
              </div>
              <br />
              <div className="col-12">
                <button
                  type="button"
                  onClick={submitForm}
                  className="btn btn-primary"
                  disabled={isSubmitting}
                >
                  {isSubmitting === true ? "Saving..." : "Save"}
                </button>
              </div>
            </Form>
          )}
        </Formik>
      </div>
    </div>
  );
}

export default withRouter(MyProfile);

groovyb [05.06.2023 12:29:39]

#

Oletko tarkastanut, ettei frontti vaan rendaa komponenttia kahdesti? Eli tilanne missä komponentti rendataan ja se suorittaa ajax kutsun, mutta syystä X render suoritetaan uudestaan jolloin eka kutsu keskeytetään ja uusi render aloittaa kutsun uudestaan (jonka firefox näyttää tuona virheilmoituksena).

eli laita vaikka lokitus tuonne useEffectin sisälle ennen API_BASE_URL + "/api/users/userdata" kutsua, ja katso kuinka monta kertaa tuo kutsu suoritetaan

walkout_ [05.06.2023 13:42:02]

#

groovyb kirjoitti:

(05.06.2023 12:29:39): Oletko tarkastanut, ettei frontti vaan rendaa...

Eli tälliannen tulee kun uuden cropatun profiilikuvan yrittää ladata palvelimelle. Ei tule mitään virheilmoitusta, jos uutta profiilikuvaa ei yritä ladata palvelmille: https://xxx.yyy.zz/api/manage/myprofile

Referrer Policy: Ignoring the less restricted referrer policy “no-referrer-when-downgrade” for the cross-site request: https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap css
Referrer Policy: Ignoring the less restricted referrer policy “no-referrer-when-downgrade” for the cross-site request: https://fonts.googleapis.com/icon?family=Material+Icons icon
Referrer Policy: Ignoring the less restricted referrer policy “no-referrer-when-downgrade” for the cross-site request: https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@6.1.2/css/fontawesome.min.css fontawesome.min.css
Referrer Policy: Ignoring the less restricted referrer policy “no-referrer-when-downgrade” for the cross-site request: https://code.jquery.com/jquery-3.2.1.slim.min.js jquery-3.2.1.slim.min.js
Referrer Policy: Ignoring the less restricted referrer policy “no-referrer-when-downgrade” for the cross-site request: https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js popper.min.js
Referrer Policy: Ignoring the less restricted referrer policy “no-referrer-when-downgrade” for the cross-site request: https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js bootstrap.min.js
Referrer Policy: Ignoring the less restricted referrer policy “no-referrer-when-downgrade” for the cross-site request: https://fonts.googleapis.com/css2?family=DM+Sans&display=swap css2
Error: Promised response from onMessage listener went out of scope 90 background.js:81:14398
true LoginForm.js:43:18
Object { user: {…}, token: "joku_token", isLogged: true, permissions: (14) […] }
auth.contexts.js:6:10
Object { resetForm: A(e), validateForm: Eh(), validateField: Eh(), setErrors: M(e), setFieldError: D(e, t), setFieldTouched: Eh(), setFieldValue: Eh(), setStatus: G(e), setSubmitting: W(e), setTouched: Eh(), … }
MyProfile.js:87:16
Object { resetForm: A(e), validateForm: Eh(), validateField: Eh(), setErrors: M(e), setFieldError: D(e, t), setFieldTouched: Eh(), setFieldValue: Eh(), setStatus: G(e), setSubmitting: W(e), setTouched: Eh(), … }
MyProfile.js:87:16
Object { x: 12.499999999999996, y: 0, width: 75.00000000000001, height: 100 }
MyProfile.js:47:14
Object { x: 0, y: 0 }
ImageCropper.js:37:12
Blob { size: 2186544, type: "image/jpeg" }
cropImage.js:65:14
Object { resetForm: A(e), validateForm: Eh(), validateField: Eh(), setErrors: M(e), setFieldError: D(e, t), setFieldTouched: Eh(), setFieldValue: Eh(), setStatus: G(e), setSubmitting: W(e), setTouched: Eh(), … }
MyProfile.js:87:16
aa MyProfile.js:101:16
Object { resetForm: A(e), validateForm: Eh(), validateField: Eh(), setErrors: M(e), setFieldError: D(e, t), setFieldTouched: Eh(), setFieldValue: Eh(), setStatus: G(e), setSubmitting: W(e), setTouched: Eh(), … }
MyProfile.js:87:16
aa MyProfile.js:101:16

walkout_ [05.06.2023 13:56:34]

#

Ok.. nyt näyttäs olevan vika korjattu. Tein virtualhost-filuun muutoskia.

<IfModule mod_headers.c>
		  Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"
		  #Header set Referrer-Policy "no-referrer-when-downgrade"
---

Eli kommmetoin pois tämän: #Header set Referrer-Policy "no-referrer-when-downgrade"

Jänää että ChatGPT väittää ettei vikaa voi korjata .htaccess-tiedostossa eikä VirtualHost-tiedostossa. Mutta ChatGPT olikin väärässä. Olin siis laittanut Apache 2 HTTP Serverin tietoturva-asetuksiin liikaa virityksiä.

groovyb [06.06.2023 08:38:53]

#

Sinänsä erikoinen tilanne, että tuo no-referrer-when-downgrade pitäisi triggeröityä vain kun tapahtuu siirto https -> http, ja tuossa tilanteessa jättää referrer otsakkeen välittämättä. En kyllä mitenkään usko että tuo on voinut tuota virhettä aiheuttaa, ellei sulla ole jotain hyvin mystistä tuossa oman saitin https tunneloinnissa taustalla joka katkaisi ja uudelleenkäynnistäisi clientin suorittaman ajax kutsun.

walkout_ [06.06.2023 08:57:59]

#

groovyb kirjoitti:

(06.06.2023 08:38:53): Sinänsä erikoinen tilanne, että tuo no-referrer...

No jos se inkkari tai minä, on koodannut vahingossa http: <--> https: siirron.

Niin juu Laravel-bäkkäri on eri domainissa kuin React-frontti. Ja käyttää nk. Cross-Site Auth -tokeenia kaikkiin AJAX-kutsuihin. Eli Redux-tekniikka.

groovyb [08.06.2023 02:01:37]

#

En ole reduxia vuosiin käyttänyt, mutta ainakin aiemmin se oli vain tilanhallintamekanismi ja ihan itse määritit actionit ja niiden sisällön, eli miten itse ajax kutsut suoritit ja palautit niiden payloadin reducerin kautta stateen. Tiedä sitte onko tuo muuttunut, mutta ainakaan aiemmin redux ei ottanut mitään kantaa itse kutsuihin, ainoastaan hoiti tilanhallinnan.

Olen yhä sitä mieltä, että joko tilanhallinnan johdosta tai useEffectin johdosta (tai niiden yhdistelmästä, koska eri tilanhallintojen yhteiskäyttö voi sotkea mekaniikkaa) suoritat kutsun, keskeytät sen ja suoritat uudestaan, aiheuttaen tuon alkuperäisen binding virheen. Tuo no-referrer lokiviesti ei liity samaan virheeseen, vaan se tulee puhtaasti tuosta että jostain syystä tapahtuu https -> http muunnos. Missä suljet itse tunneloinnin? Nginx/apache/jne päässä ja ohjaat reverse proxyllä laraveliin?

Tuo eri domain aiheuttaa ongelmia vain corsin osalta, jos et ole sallinut tuota react frontista lähtevän kutsun originia, jos se sinulla on käytössä.

*Edit*

Tuossa koodissasi et myöskään käytä reduxia missään, joten vähän hämmästelen mihin viittaat sen käytöllä. Et ainakaan dispatchää mitään tuossa joten redux ei suorita mitään reduceria, vaan käytät normaaleja react hookkeja. Onko se tuon authContextin puolella? Jos on niin eikös sinun tulisi useEffectissä varmentaa ennen mitään suorituksia, että tuo konteksti on edes populoitu. authStatea et ainakaan käytä missään, joten jos se on tuo kyseinen state mihin reducer läimii bearer tokenit, kutsussa kuitenkin luet arvon localstoragesta. Melko hämärä pattern kyllä sulla tossa käytössä.

Tuossa olet sotkenut monia eri asioita tarpeettomasti sekaisin. Jos haluat käyttää kontekstia, wräppää sillä lapsiksi komponentit jotka haluat että kontekstia hyödyntää. Tuossa olet jotenkin sotkenut kontekstin react hookkiin, ihan kuin konteksti itsessään suorittaisi jonkun promisen siinä vaiheessa kun lataat sen. hyvin erikoinen pattern verrattuna tähän normaaliin keissiin miten konteksteja käytetään:

import { useState, createContext, useContext } from "react";
import ReactDOM from "react-dom/client";

const fooContext = createContext();

function Component1() {
  const [bar, setBar] = useState("Foobar");

  return (
    <fooContext value={bar}>
      <h1>{`Hello ${bar}!`}</h1>
      <Component2 />
    </UserContext.Provider>
  );
}

function Component2() {
  const bar = useContext(fooContext);

  return (
    <>
      <h1>Component 2</h1>
      <h2>{`Hello ${bar} again!`}</h2>
    </>
  );
}
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Component1 />);

Jos taas tuo "kontekstisi" on vaan käytännössä helper ja suoritat sen sisältä actioneja jotka suorittaa reduxin sälää, ei sinun tarvitse sitä alunperinkään kontekstina käyttää vaan niiden tulosten pitäisi Providerin kautta propsin storeen populoitua.

noutti [08.06.2023 08:22:10]

#

Käytä ihan oikeasti react-querya projektissasi. Pääset eroon monista ongelmista.

walkout_ [09.06.2023 01:54:42]

#

groovyb kirjoitti:

(08.06.2023 02:01:37): En ole reduxia vuosiin käyttänyt, mutta ainakin...

Redux on käytössä allaolevassa koodissa:

useEffect(() => {
    request()
      .get(API_BASE_URL + "/api/users/userdata", {
        headers: {
          Authorization: "Bearer " + localStorage.getItem(ACCESS_TOKEN_NAME),
        },
      })
      .then((res) => {
        setData(res.data);

      });
  }, []);

Eli tämä:

Authorization: "Bearer " + localStorage.getItem(ACCESS_TOKEN_NAME)

Eli tämä request() on itse koodattu muualla koodissa oleva utility, jossa on Redux-koodi.

groovyb [12.06.2023 15:08:43]

#

Tuo ei kyllä näytä siltä että reduxia olisi käytössä yhtään missään, näytätkö sen pätkän missä dispatch ja storehallinta hoidetaan. Onko sen tarkoitus siis populoida localstorageen tuo access token? Jos ei, niin tuo menisi ihan normaalilla fetchillä koska saatu data lyödään normaalisti hookilla talteen tuossa data/setData combossa

walkout_ [13.06.2023 10:23:14]

#

groovyb kirjoitti:

(12.06.2023 15:08:43): Tuo ei kyllä näytä siltä että reduxia olisi...

Redux on asennettu tähän SDK:hon kyllä kevytyrittäjän toimesta, joka on peräisin Upwork-palvelusta ja hän ainakin väitää, että Redux on käytössä ks. ohjelmistokehtiysalustassa.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta