yewstack / yew

Rust / Wasm framework for creating reliable and efficient web applications
https://yew.rs
Apache License 2.0
30.82k stars 1.43k forks source link

Tutorial proxy-backend returning `index.html` not json? #3562

Open ydirson opened 11 months ago

ydirson commented 11 months ago

Note: I think I followed the tuto right, but it may well be a user error - what really happens behind my back in trunk serve --proxy-backend indeed worries me.

Problem In the last step of the tutorial, the trunk serve process does report proxying as expected:

2023-12-16T23:28:47.916146Z  INFO 📡 proxying /tutorial -> https://yew.rs/tutorial

but the call to json() on the Response object fails with a parse error, caught by unwrap():

panicked at src/main.rs:74:22:
called `Result::unwrap()` on an `Err` value: SerdeError(Error("expected value", line: 1, column: 1))

When querying its text() instead I get something looking like dist/index.html, excep:

"<!DOCTYPE html><html lang=\"en\"><head>\n<link rel=\"preload\" href=\"/yew-tuto-56dc19c1d2397a2a9d7ed57de056ad246e9780a244ab777c8af3501c5b435ab460786da12a03b5d575a5b77bb0c0b951_bg.wasm\" as=\"fetch\" type=\"application/wasm\" crossorigin=\"anonymous\" integrity=\"sha384-VtwZwdI5eiqdftV94FatJG6XgKJEq3d8ivNQHFtDWrRgeG2hKgO11XWlt3uwwLlR\">\n<link rel=\"modulepreload\" href=\"/yew-tuto-56dc19c1d2397a2a9d7ed57de056ad246e9780a244ab777c8af3501c5b435ab460786da12a03b5d575a5b77bb0c0b951.js\" crossorigin=\"anonymous\" integrity=\"sha384-abm7hNroHgmO-4dhhx1owgizoubsoronoQebv8kzdegbKJXclKG1Se4cNkK9b48k\"></head>\n    <body>\n\n\n<script type=\"module\">\nimport init, * as bindings from '/yew-tuto-56dc19c1d2397a2a9d7ed57de056ad246e9780a244ab777c8af3501c5b435ab460786da12a03b5d575a5b77bb0c0b951.js';\ninit('/yew-tuto-56dc19c1d2397a2a9d7ed57de056ad246e9780a244ab777c8af3501c5b435ab460786da12a03b5d575a5b77bb0c0b951_bg.wasm');\nwindow.wasmBindings = bindings;\n\n</script><script>\"use strict\";\n\n(function () {\n\n    const address = 'localhost:8080';\n    let protocol = '';\n    protocol =\n        protocol\n

when my index.html reads:

<!DOCTYPE html><html lang="en"><head>
<link rel="preload" href="/yew-tuto-dfbd59d34641e15def5e2ad596d898d62fbcc1fa07f7416e23f9e3fcac1b96cac82ac4ddd0b1765a62a49daf68df933a_bg.wasm" as="fetch" type="application/wasm" crossorigin="anonymous" integrity="sha384-371Z00ZB4V3vXirVltiY1i-8wfoH90FuI_nj_KwblsrIKsTd0LF2WmKkna9o35M6">
<link rel="modulepreload" href="/yew-tuto-dfbd59d34641e15def5e2ad596d898d62fbcc1fa07f7416e23f9e3fcac1b96cac82ac4ddd0b1765a62a49daf68df933a.js" crossorigin="anonymous" integrity="sha384-T7wdMh576Bm4zh1ka8x7ATfiVk0hQi1dd3noLX_rCbtJmfmE_W9PnMYJdEjnGnIW"></head>
    <body>

<script type="module">
import init, * as bindings from '/yew-tuto-dfbd59d34641e15def5e2ad596d898d62fbcc1fa07f7416e23f9e3fcac1b96cac82ac4ddd0b1765a62a49daf68df933a.js';
init('/yew-tuto-dfbd59d34641e15def5e2ad596d898d62fbcc1fa07f7416e23f9e3fcac1b96cac82ac4ddd0b1765a62a49daf68df933a_bg.wasm');
window.wasmBindings = bindings;

</script><script>"use strict";

(function () {

    const address = '{{__TRUNK_ADDRESS__}}';
    let protocol = '';
...

curl http://127.0.0.1:8080/tutorial/data.json does dump me the expected JSON (and I also tried to add an intermediate tutorial step just for decoding, see repo, but I'm not pleased with how it diverges too much to be useful)

Steps To Reproduce

I uploaded my steps to https://github.com/ydirson/test-yew-tutorial

Steps to reproduce the behavior:

  1. checkout commit 'use a proxy server' to see the .json().unwrap() fail
  2. checkout commit DBG to see the text() dump

Environment:

Questionnaire

notno commented 9 months ago

Same issue here

ranile commented 8 months ago

I just ran curl https://yew.rs/tutorial/data.json and it returns the JSON for me. It appears you are querying the tutorial home page instead of the data.json file. The home page will of course returns HTML so it can be rendered by the browser

FelixSeol commented 8 months ago

Same issue.

let fetched_videos: Vec<Video> = Request::get("/tutorial/data.json")
                    .send()
                    .await
                    .unwrap()
                    .json()
                    .await
                    .unwrap();

with this code, I ran trunk serve --proxy-backend=https://yew.rs/tutorial it returns

panicked at src/main.rs:67:22:
called `Result::unwrap()` on an `Err` value: SerdeError(Error("expected value", line: 1, column: 1))

but curl returns fine.

$ curl http://127.0.0.1:8080/tutorial/data.json
[
    {
        "id": 1,
        "title": "Building and breaking things",
        "speaker": "John Doe",
        "url": "https://youtu.be/PsaFVLr8t4E"
    },
    {
        "id": 2,
        "title": "The development process",
        "speaker": "Jane Smith",
        "url": "https://youtu.be/PsaFVLr8t4E"
    },
    {
        "id": 3,
        "title": "The Web 7.0",
        "speaker": "Matt Miller",
        "url": "https://youtu.be/PsaFVLr8t4E"
    },
    {
        "id": 4,
        "title": "Mouseless development",
        "speaker": "Tom Jerry",
        "url": "https://youtu.be/PsaFVLr8t4E"
    }
]
FelixSeol commented 8 months ago

In my case, it turns out browser issue.

chrome Console returns

127.0.0.1/:2 The integrity attribute is currently ignored for preload destinations that do not support subresource integrity. See https://crbug.com/981419 for more information

I don't know what that means exactly, but I guess it cannot get data.json correctly and leads 'serde error'.

Safari, Firefox, Edge work fine.

mDanone commented 7 months ago

Had the same issue on mac m1 pro, Sonoma 14.3 with 5000 port, swithed to 8000 port and it started working pretty well. So the next step was turn 5000 back, so it continued working well. I think it is may be because of some cache issues because i noticed that first request was a bit longer then next.

Olaoluwa26 commented 6 months ago

Thank you @mDanone, changing ports helped.

BartMassey commented 5 months ago

The problem I had here, for Firefox at least, is that once the client gets a CORS error Firefox won't allow the request to be retried once the proxy server is up. Even shift-reload doesn't seem to reset things. Easy workaround is to just connect again in a new tab.

Is there some reason yew.rs doesn't just have a CORS policy that allows access to the data, rather than needing a proxy server?

DavidAntliff commented 4 months ago

I'm having the exact same problem (Firefox) - the download isn't data.json but something that starts out with this:

<!doctype html>
<html lang="en">
<head>
<link rel="modulepreload" href="/yew-app-4e192d3122da419a.js" crossorigin=anonymous integrity="sha384-l37IIPAgQSy/RE9SAaBLuMvkS3VP/bSold2x8DL7dYz+feNCiJ88OiWP/ngSL8PQ">
<link rel="preload" href="/yew-app-4e192d3122da419a_bg.wasm" crossorigin=anonymous integrity="sha384-kIu9dgrSuuD13cwfyhAd/N5XAqSmf54tKzqQpyiZ5X+ixo58PaFULW5G0dUE52gd" as="fetch" type="application/wasm"></head>
<body>
<script type="module" nonce="jr3bgc5cG3jHKCfwSjrq4w==">
import init, * as bindings from '/yew-app-4e192d3122da419a.js';
const wasm = await init('/yew-app-4e192d3122da419a_bg.wasm');

...

Yet, curl http://127.0.0.1:8080/tutorial/data.json returns the expected JSON doc.

As per the tutorial, I'm running: trunk serve --proxy-backend=https://yew.rs/tutorial

And my fetch code is:

                let fetched_videos: Vec<Video> = Request::get("/tutorial/data.json")
                    .send()
                    .await
                    .unwrap()
                    .json()
                    .await
                    .unwrap();   // <<<< PANIC IS HERE

I feel like I'm doing something obviously wrong, but I can't work out what!

Note: opening in a new tab doesn't help, neither does forced refresh, or restarting trunk.

Interestingly, if I run trunk serve --proxy-backend=https://yew.rs/tutorial --port 8081 (changing the port to 8081), it now works. Huh?

MacGurk commented 4 months ago

Seems to be indeed a caching issue. Had the same issue in Firefox, first run the Request directly with the CORS issue and after running it with trunk serve --proxy-backend=https://yew.rs/tutorial it wouldn't load the json data. But after finding this issue I tried different browsers and a different port and it worked, but it would still not work with a different tab or fresh restart of Firefox. After clearing all temporary cached site data in Firefox it now works with the default port 8080 as well!