Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug: iframe src attribute set incorrectly in jsx #25196

Closed
zachsiegel-capsida opened this issue Sep 6, 2022 · 20 comments
Closed

Bug: iframe src attribute set incorrectly in jsx #25196

zachsiegel-capsida opened this issue Sep 6, 2022 · 20 comments
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug

Comments

@zachsiegel-capsida
Copy link

My MWE is a very simple iframe:

<iframe src="https://content.com"></iframe>

This works just fine (full iframe code below).

If I wrap the src attribute's value in curly braces (code below), I get the following:

<iframe src={"https://content.com"}></iframe>

image

image

The actual iframe content is an embedded Powerpoint presentation:

<iframe
src="https://capsida.sharepoint.com/sites/sitename/_layouts/15/Doc.aspx?sourcedoc={xxxxxx}&amp;action=embedview"
width="476px"
height="288px"
frameBorder="0">
</iframe>

React version:

Steps To Reproduce

  1. Open this Stackblitz. You should not be able to see the embedded Powerpoint content, but the iframe should load correctly (you should see a Microsoft login screen).
  2. Wrap the src="https://..." in curly braces: src={"https://..."} and save the component. Now the iframe does not load! You can see the screenshots below to observe this phenomenon:

image

image

The current behavior

My real example is something like src={url}, where url is a state variable. The issue is not that I want to wrap the attribute in curly braces, it's that this iframe loads differently when the attribute is hard-coded into the jsx versus loaded from javascript via curly braces {url}.

I also recognize that Microsoft's Powerpoint embedding logic may forbid cross-origin embedding, and I want to emphasize that this is clearly not the issue here despite the Chrome console message. If cross-origin embedding was the issue, the iframe should equally fail with or without curly braces.

The expected behavior

I expect the iframe to load (or not load) the same way regardless of whether its src attribute is passed as an HTML attribute in jsx (src="https://...") or as a jsx attribute (src={"https://..."}).

@zachsiegel-capsida zachsiegel-capsida added the Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug label Sep 6, 2022
@Noah670
Copy link

Noah670 commented Sep 7, 2022

iFrames are chaotic evil in react

@zachsiegel-capsida
Copy link
Author

@Noah670 99.9% of the time I would assume I am doing something wrong and that the React developers would call my issue a mis-use rather than a bug, but I think my MWE is very compelling. I doubt many people would see the MWE and expect it to succeed/fail depending on those curly braces.

@zachsiegel-capsida
Copy link
Author

Created this Stackblitz documenting several attempted solution paths referenced here, here, and here.

@FrameMuse
Copy link

FrameMuse commented Sep 16, 2022

I just ran your code and it works as intended, I think you have a problem with word breaks, in the screenshots you have a break at {f8c, it might be just adding \n to your url.

I tested it via const url = "...", via jsx {"..."}, "..." - every method works the same.

And I'm not a React Maintainer :)

@FrameMuse
Copy link

If I wrap the src attribute's value in curly braces (code below), I get the following:

<iframe src={"https://content.com"}></iframe>

image

This is funny how you put https://content.com and getting error with capsida.sharepoint.com.

@zachsiegel-capsida
Copy link
Author

zachsiegel-capsida commented Sep 16, 2022

@FrameMuse thank you for this response! I'm not sure what I'm missing, please help me out:

  • The "break" in my URL at {f8c is just word wrap - there is no newline there at all.
  • If you run the Stackblitz, do you indeed see the iframes embedding the page successfully with the JSX-style src={"..."} attribute?

To clarify, I wrote https://content.com to make it easier to glance at the code. I included the full embedded link (to some non-sensitive published test content from my company's Microsoft Sharepoint service) in the Stackblitz.

I don't claim that every iframe will fail to render with a JSX-style src attribute, and I have certainly used this pattern with other embedded content successfully. My question is why for any content would using a JSX-style attribute cause some sort of error (cross-origin or otherwise) when using regular HTML attributes within the same JSX component would succeed?

@FrameMuse
Copy link

@zachsiegel-capsida I clearly see that the attribute src is putting correctly, but the content is loading endlessly (probably because of my location or any other reason).

I drop a screenshot for you
image

@FrameMuse
Copy link

Did you tested it in a "local environment" (I mean server that is running locally on your computer) or only on Stackblitz?

@FrameMuse
Copy link

And also in your example with iframe code you misput action=embedview to src attribute, see it in your code

<iframe
src="https://capsida.sharepoint.com/sites/sitename/_layouts/15/Doc.aspx?sourcedoc={xxxxxx}&amp;action=embedview"
width="476px"
height="288px"
frameBorder="0">
</iframe>

It should be

<iframe
src="https://capsida.sharepoint.com/sites/sitename/_layouts/15/Doc.aspx?sourcedoc={xxxxxx}&amp;"
width="476px"
height="288px"
frameBorder="0"
action="embedview">
</iframe>

@devjs1000
Copy link

devjs1000 commented Oct 8, 2022

after seeing the link and what you are trying to do
there is nothing wrong with jsx and the react.

the link or website you are trying to access has x-frame same-origin enable it means that you can't use it in iframes.

definition:

you have to check for HTTP response header X-Frame-Option of those sites. if its value is "DENY or SAMEORIGIN", then you can not load those website in the iframes. DENY = No one can load the website in iframe. Even the same domain page wont be able to load.

@FrameMuse
Copy link

after seeing the link and what you are trying to do there is nothing wrong with jsx and the react.

the link or website you are trying to access has x-frame same-origin enable it means that you can't use it in iframes.

definition:

you have to check for HTTP response header X-Frame-Option of those sites. if its value is "DENY or SAMEORIGIN", then you can not load those website in the iframes. DENY = No one can load the website in iframe. Even the same domain page wont be able to load.

As I wrote above, there is a problem with action attribute, the website denies access when it's not embedview.

@devjs1000
Copy link

after seeing the link and what you are trying to do there is nothing wrong with jsx and the react.
the link or website you are trying to access has x-frame same-origin enable it means that you can't use it in iframes.

definition:

you have to check for HTTP response header X-Frame-Option of those sites. if its value is "DENY or SAMEORIGIN", then you can not load those website in the iframes. DENY = No one can load the website in iframe. Even the same domain page wont be able to load.

As I wrote above, there is a problem with action attribute, the website denies access when it's not embedview.

not it is not the case
the website is doing this because the data same origin is written in its header.
this practice is used for protecting data from hackers by web devs.

@FrameMuse
Copy link

after seeing the link and what you are trying to do there is nothing wrong with jsx and the react.
the link or website you are trying to access has x-frame same-origin enable it means that you can't use it in iframes.

definition:

you have to check for HTTP response header X-Frame-Option of those sites. if its value is "DENY or SAMEORIGIN", then you can not load those website in the iframes. DENY = No one can load the website in iframe. Even the same domain page wont be able to load.

As I wrote above, there is a problem with action attribute, the website denies access when it's not embedview.

not it is not the case the website is doing this because the data same origin is written in its header. this practice is used for protecting data from hackers by web devs.

I had the error in console too, but when I put the attribute it disappreared and you're saying this is not the case, how's that?
Also, this iframe code should work because it's literally how it intented to be. This is a feature of Microsoft Powerpoint - you can share it (with iframe).

@zachsiegel-capsida
Copy link
Author

zachsiegel-capsida commented Oct 13, 2022

@FrameMuse

And also in your example with iframe code you misput action=embedview to src attribute, see it in your code

<iframe
src="https://capsida.sharepoint.com/sites/sitename/_layouts/15/Doc.aspx?sourcedoc={xxxxxx}&amp;action=embedview"
width="476px"
height="288px"
frameBorder="0">
</iframe>

It should be

<iframe
src="https://capsida.sharepoint.com/sites/sitename/_layouts/15/Doc.aspx?sourcedoc={xxxxxx}&amp;"
width="476px"
height="288px"
frameBorder="0"
action="embedview">
</iframe>

This has nothing to do with whether the iframe src URL contains &action=embedview versus adding the action="embedview" attribute to the iframe. I tried both ways and they both work/fail the same way; these iframe snippets were generated from MS Powerpoint with &action=embedview and I suspect that should work.

As I have mentioned, regardless of whether changing other iframe attributes could result in properly loaded content, the fact is that in no case should a JSX-style attribute result in different behavior from an HTML-style attribute (i.e. src="http://..." should always function the same as src={"http://..."}). If I'm wrong about that part I'd love to hear why, but nobody has commented on that.

@zachsiegel-capsida
Copy link
Author

@devjs1000

after seeing the link and what you are trying to do there is nothing wrong with jsx and the react.

the link or website you are trying to access has x-frame same-origin enable it means that you can't use it in iframes.

definition:

you have to check for HTTP response header X-Frame-Option of those sites. if its value is "DENY or SAMEORIGIN", then you can not load those website in the iframes. DENY = No one can load the website in iframe. Even the same domain page wont be able to load.

As I have mentioned, I understand that there are many reasons why an iframe might not load, and I absolutely understand same-origin policies. The issue is that the behavior is different using JSX-style versus an HTML-style src attribute (i.e. src={"http://..."} versus src="http://...") - they should either both fail or both succeed if a same-origin policy is to blame.

@zachsiegel-capsida
Copy link
Author

@FrameMuse

Did you tested it in a "local environment" (I mean server that is running locally on your computer) or only on Stackblitz?

Yes, I experienced this issue in a local React environment (serving on localhost) as well as on a staging server (an AWS EC2 instance) before creating this MWE on Stackblitz. In all cases, the iframe has the same problem.

@devjs1000
Copy link

devjs1000 commented Oct 13, 2022

@zachsiegel-capsida
can you tell me the browser you are using and version

@zachsiegel-capsida
Copy link
Author

@devjs1000 I am using the latest Chrome. Still having a tough time with this!

@zachsiegel-capsida
Copy link
Author

zachsiegel-capsida commented Oct 27, 2022

SOLVED!

Per this StackOverflow comment, the string &amp; in Javascript strings works slightly differently from HTML. In iframe src attributes in HTML, it's not necessary to escape ampersands in this way, so I don't know why Microsoft's Sharepoint "embed" snippets are made that way.

I am able to change src={url} to src={sanitizeUrl(url)} where sanitizeUrl is the following function:

function sanitizeUrl(url) {
	return url.replaceAll('&amp;', '&')
}

I would consider this issue closed.

@punyapatkha
Copy link

punyapatkha commented Jan 18, 2023

i faced the same issue.
sanitizeUrl also work for me

thank you very much! @zachsiegel-capsida

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Unconfirmed A potential issue that we haven't yet confirmed as a bug
Projects
None yet
Development

No branches or pull requests

5 participants